// Treiber zum Ausgabe auf der Flüssigkristallanzeige
// LCD DSM-0822A von Pollin ( I2C-Controller PCF8576)8 Stellen alphanumerisch
// Zeicheausgabe, Stringausgabe, Zahlenausgabe
//
// Michael Dworkin
// 07.06.2004
// Compiler CC5x

// Hier sind die Zeichen kodiert, die 2 Hexadezinahlwerte geben an
// welche von 16 Segmenten geschaltet werden, weitere infos auf http://cc5x.de.vu
const char Tab[128] =
{
    0x00,0x00,
    0x04,0x20,   //21h (33) !
    0x80,0x20,   //22h (34) "
    0xa8,0x8c,   //23h (35) # -> ° (Grad-Zeichen)
    0xad,0xb5,   //24h (36) $
    0xec,0x37,   //25h (37) %
    0x3b,0x71,   //26h (38) &
    0x00,0x02,   //27h (39) '
    0x00,0x42,   //28h (40) (
    0x42,0x00,   //29h (41) )
    0x66,0x66,   //2ah (42) *
    0x24,0x24,   //2bh (43) +
    0x40,0x00,   //2ch (44) ,
    0x00,0x04,   //2dh (45) -
    0x01,0x00,   //2eh (46) .
    0x40,0x02,   //2fh (47) /
    0x99,0x99,   //30h (48) 0
    0x00,0x0b,   //31h (49) 1
    0x39,0x9c,   //32h (50) 2
    0x29,0x9d,   //33h (51) 3
    0xa0,0x0d,   //34h (52) 4
    0xa9,0x95,   //35h (53) 5
    0xb9,0x95,   //36h (54) 6
    0x08,0x89,   //37h (55) 7
    0xb9,0x9d,   //38h (56) 8
    0xa9,0x9d,   //39h (57) 9
    0x21,0x00,   //3ah (58) :
    0x21,0x00,   //3bh (59) ;
    0x00,0x42,   //3ch (60) <
    0x21,0x00,   //3dh (61) =
    0x42,0x00,   //3eh (62) >
    0x8c,0x8c,   //3fh (63) ?
    0x3d,0x99,   //40h (64) @
    0xb8,0x8d,   //41h (65) A
    0x0d,0xbd,   //42h (66) B
    0x99,0x90,   //43h (67) C
    0x0d,0xb9,   //44h (68) D
    0xb9,0x94,   //45h (69) E
    0xb8,0x84,   //46h (70) F
    0x99,0x95,   //47h (71) G
    0xb0,0x0d,   //48h (72) H
    0x0d,0xb0,   //49h (73) I
    0x11,0x19,   //4ah (74) J
    0xb0,0x42,   //4bh (75) K
    0x91,0x10,   //4ch (76) L
    0x92,0x0b,   //4dh (77) M
    0x92,0x49,   //4eh (78) N
    0x99,0x99,   //4fh (79) O
    0xb8,0x8c,   //50h (80) P
    0x99,0xd9,   //51h (81) Q
    0xb8,0xcc,   //52h (82) R
    0xa9,0x95,   //53h (83) S
    0x0c,0xa0,   //54h (84) T
    0x91,0x19,   //55h (85) U
    0xd0,0x02,   //56h (86) V
    0xd0,0x49,   //57h (87) W
    0x42,0x42,   //58h (88) X
    0xa1,0x1d,   //59h (89) Y
    0x49,0x92,   //5ah (90) Z
    0x99,0x00,   //5bh (91) [
    0x02,0x40,   //5ch (92) \
    0x00,0x99,   //5dh (93) ]
    0x40,0x40,   //5eh (94) ^
    0x01,0x10   //5fh (95) _
};

// Initialisieren der Anzeige, auch zum Löschen verwendbar
void LCD_Init(void)
{
    char i;
    bstart();
    schreib(112);   // feste adresse
    schreib(0b.1110.0000);  // Device select
    schreib(0b.1100.1000);  // Mode set(enabled)
    for (i=0;i<19;i++) schreib(0);  //LCD Löschen
    bstop();
}

// Ein Zeichen ausgeben an bestimmter posizion(0...7)
void Ausgabe(char Pos, char a)
{
    bstart();           // Startbedinung
    schreib(112);       // adresse
    schreib(Pos*4);     // Adresse des Zeichens am LCD
    a=a-32;             // Berechnung des Zeichenposizion in Tabelle
    a=a*2;              // aus dem ASCII-Wetrt der übergebenen Zeichen.
    schreib(Tab[a]);    // erste Byte
    schreib(Tab[a+1]);  // zwiete Byte
    bstop();            // Stoptbedinung
}
//Ein String(Zeichenkette) an die LCD-Anzeige senden
void LCDString(char pos,const char *str)
{
    char ps,z;
    ps = *str;      // Pointer auf start des Strings ins ps
    z=pos;
    while(ps>0)     // Pruefen ob String zu ende ist
    {
        str++;              // Pointer auf nexte Zeihen erhoehen
        if (ps== 0) break;  // Pruefen ob String zu ende ist
        Ausgabe(z,ps);      // Zeichen aus dem String Anzeigen
        ps = *str;          // Inhalt des ponters ins ps
        z++;                // Posizion für nexte Zeichen ausrechnen
    }
}

// Variableninhalt als Zahl an LCD anzeigen
// Bitte anzahl Dezimahlstellen einstellen! Hier sind 3 eingestellt. 
void ZalString(char pos, uns16 z)
{
    uns16 i,temp,Dez;
    char o;
    o=pos;
    bit k;                      // Merker ob vorne 0 ist
    k=0;
    Dez=100;     // !!!  // Dezimalstellen, z.B. bei 2 Stellen 10 eintragen
    while (Dez)                 // Solange Dezimalstelle nicht 0 ist
    {
        if(Dez==1) k=1;         // Um ein einzige 0 anzeigen können
        i=z/Dez;                // Wert der jeweilige Dezimalstelle bestimmen
        temp=i*Dez;
        z=z-temp;
        if(i||k)                // Damit wir vorne keine Nullen stehen haben.
        {
            Ausgabe(o, (char)i+0x30);
            k=1;                // es gab schon eine Zahl die nicht 0 ist
        }
        else                    // wen 0 ist und vorne keine Zahl war, dann
        {
            Ausgabe(o, ' ');    // Leerzeichen ausgeben
        }
        o++;
        Dez=Dez/10;
    }
}
