Forum: Mikrocontroller und Digitale Elektronik LCD eigene Zeichen


von Marco H. (purzelbaum)


Lesenswert?

Hallo,

Einmal vorweg :-) Ich weiß, dass es schon viele solche Themen gibt und 
ich hab auch schon so einige durchgelesen.

So also ich hab folgendes problem. Ich möchte mit meinem LCD eigene 
Zeichen schreiben. Lese die Bytes seriell ein. Protokoll ist 
Crystalfontz

if(data==25)
}
while(!DataRdyUSART());
data=getcUSART();
if(data==0)
{
  lcd_data(0x40);
  cgr=0x00;
}
if(data==1)
{
  lcd_data(0x48);
  cgr=0x01;
}
if(data==2)
{
  lcd_data(0x50);
  cgr=0x02;
}
if(data==3)
{
  lcd_data(0x58);
  cgr=0x03;
}
if(data==4)
{
  lcd_data(0x60);
  cgr=0x04;
}
if(data==5)
{
  lcd_data(0x68);
  cgr=0x05;
}
if(data==6)
{
  lcd_data(0x70);
  cgr=0x06;
}
if(data==7)
{
  lcd_data(0x78);
  cgr=0x07;
}
for(i=0;i<8;i++)
{
  while(!DataRdyUSART());
  data=getcUSART();
  lcd_write(data);
}
lcd_data(line1);
lcd_write(cgr);

So wenn der PIC nun am ende der schleife ankommt passiert nichts :-)
Hoffe ihr habt eine Idee :-)

Gruß Marco

von Ztalam (Gast)


Lesenswert?

Leider keine ausreichende Infomationen.
Bitte Frage neu formulieren.
Siehe 
http://www.mikrocontroller.net/articles/Netiquette#Klare_Beschreibung_des_Problems

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dieser Codeschnippsel sieht korrekt aus (bis auf if(data==25)}). Der 
Fehler liegt wo anders.

von Marco H. (purzelbaum)


Lesenswert?

Moin also ich hab etwas neues rausgefunden.
Entschuldigt, wenn dies nur ein "Code-Schnipsel" ist, aber auch nur dort 
liegt der Fehler. Ich kann mit meinen Routinen ganz normal Zeichen auf 
dem Display ausgeben.

So nun zu dem, was ich rausgefunden habe.
Normal läuft es ja so ab.

1. RS=0 und Adresse 0x40 laden
2. RS=1 und Daten an das LCD schicken (8x und ich hab 
auto-Inkrementierung)
3. RS=0 und Adresse 0x80 laden oder die Zeile in die man schreiben 
möchte

Zu 1.: Ich weiß nicht, ob das klappt :-) Ich vermute(auch wenn man keine 
Vermutungen machen soll), das 1. nicht geht

Zu 2.: Nun könnte ich ja z.B. 8x 0bXXX11111 schreiben. XXX wird ja 
überlesen. Gebe ich aber 0b00110010 ein müsste ja eigentlich 0bXXX10010 
gelesen werden. Aber es wird auf das LCD eine 2 geschrieben. Das dürfte 
doch gar nicht, weil ich ja in das CG Ram schreibe.

Zu 3.: Dadurch das ich bei 2. z.B 0x80 in das DD Ram schreibe gehe ich 
ja nur wieder auf Zeile 1.

Oder hab ich irgendetwas falsch verstanden? :-)

Gruß Marco

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sagt das Datenblatt deines LCD, dass das bei diesem LCD das CGRAM 
(Zeichengenerator) bei 0x40 beginnt?

Kannst du reguläre Zeichen (ASCI-Zeichen) über die Adressierung im DDRAM 
(Textpuffer) ablegen und an der Wunschposition ausgeben? Liegt lt. 
Datenblatt bei deinem LCD der Textpuffer bei 0x80?

Du hast eine kleine Verknotung bei den Funktionsnamen; die Funktionen 
benennt man üblicherweise anders


Funktion          "Normal"         Du
========================================
Byte mit RS=0    lcd_command   lcd_data
an LCD
= Steuerkommando

Byte mit RS=1    lcd_data      lcd_write
an LCD
= reg. Ausgabe

Deine Codeschnippsel würde ich leicht umordnen:
1
#define ESC_EIGENES_ZEICHEN 25
2
#define CGRAM_LCD 0x40  // Wert im Datenblatt nachsehen!
3
#define DDRAM_LCD 0x80  // Wert im Datenblatt nachsehen!
4
5
// Verknotete Programmierung :-)
6
#define LCD_COMMAND(a)  lcd_data((a))   // Byte an LCD mit RS=0
7
#define LCD_DATA(a)     lcd_write((a))  // Byte an LCD mit RS=1
8
9
  // ...hier kommt ein Zeichen in data für die 
10
  // Ausgabe auf dem LCD an...
11
12
  if( data == ESC_EIGENES_ZEICHEN )
13
  {
14
    // Nächste 1+8 Bytes für eigenes Zeichen verwenden
15
    // 1. Byte: Nummer des Zeichens 0..7
16
    while( !DataRdyUSART() );
17
    data = getcUSART();
18
    cgr = data % 8; // Nummer des Zeichens auf 0..7 begrenzen
19
    data = CGRAM_LCD + cgr * 8; // Startadresse im CGRRAM festlegen
20
    LCD_COMMAND(data);  // Schreibadresse CGRAM festlegen
21
    for(i=0;i<8;i++) // 8 Bytes: Bitmuster ins CGRAM übertragen
22
    {
23
      while( !DataRdyUSART() );
24
      data = getcUSART();
25
      LCD_DATA(data);
26
      // der CGRAM-Adresszähler inkrementiert automatisch
27
    }
28
    // Eigenes Zeichen jetzt ausgeben
29
    LCD_COMMAND(DDRAM_LCD); // Zeiger im DDRAM auf Anfang setzen
30
    LCD_DATA(cgr);
31
  }

von Marco H. (purzelbaum)


Lesenswert?

Wow danke Stefan.
Das mit lcd_data und lcd_write wurde mir auch schon einmal gesagt, aber 
wie du es geschrieben hast lässt es sich schnell ändern. Werde das aber 
komplett in meiner .c und .h ändern :-)

Ich versuche mal deinen Code aus.
Wenn es nicht geklappt hat, was ich nicht hoffe, dann poste ich nochmal.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.