Forum: Mikrocontroller und Digitale Elektronik LCD halb defekt?


von Der L. (vhdl-neuling)


Lesenswert?

Hallo zusammen,

ich lerne aus meinen Fehlern am Wochenende und poste mal einen neuen 
Thread :)

Alsooo: habe das 16x1 LCD-Display von Reichelt (161A) und habe folgendes 
Problem.
Ich habs initialisiert (8-bit-Modus, 1-zeilig) und ich kann auch schön 
was in die ersten 8 Stellen schreiben. ABER die 2. acht Stellen kann ich 
nicht ansprechen. Wenn ich das Display 2-zeilig initialisiere, kommt gar 
nichts. Wenn ich einen elend langen String aufs Display schicke 
(1-zeilig), kommt nach exakt 80 Zeichen erneut etwas auf den ersten 8 
Stellen des Displays.

Das habe ich mir so erklärt: Das Data-Display-RAM ist 0x4F bits breit 
und wenn der Cursor da einmal durchgelaufen ist, gehts von vorne wieder 
los.

Im Datenblatt steht, dass 0x40 bis 0x47 im RAM die Stellen 9-16 
repräsentieren, aber das kann ja irgendwie nicht sein. Kann es sein, 
dass die Stellen 9-16 einfach falsch oder gar nicht gemappt sind?

Anders kann ich es mir nicht erklären.

Danke schonmal,
derLars

von Benedikt K. (benedikt)


Lesenswert?

Der Lars wrote:
> Ich habs initialisiert (8-bit-Modus, 1-zeilig) und ich kann auch schön
> was in die ersten 8 Stellen schreiben. ABER die 2. acht Stellen kann ich
> nicht ansprechen.

Das ist normal, denn das Display ist 2 Zeilig, die zweite Hälfte ist 
elektrisch gesehen die zweite Zeile.

> Wenn ich das Display 2-zeilig initialisiere, kommt gar nichts.

Dann dreh mal den Kontrast höher.

von Klaus (Gast)


Lesenswert?

1. Hälfte Adr. 0x00
2. Hälfte Adr. 0x50

von Benedikt K. (benedikt)


Lesenswert?

Klaus wrote:

> 2. Hälfte Adr. 0x50

Nein, 0x40 ist schon richtig.

von Lupin (Gast)


Lesenswert?

Also die zweite Hälfte beginnt ab 0x40 (nicht 0x50).

Ist irgendwie doof gemacht, ich hab mir eine Funktion geschrieben welche 
schaut wo das Zeichen hin soll und danach dann die entsprechende "Zeile" 
auswählt (also vor jedem Schreiben den Cursor manuell setzen).

Den PIC Code hatte ich hier mal hoch geladen:
Beitrag "LM75 Thermometer"

Interessant für dich sind wohl die Funktionen InitLcd und PrintLCD_Char.

von Der L. (vhdl-neuling)


Lesenswert?

Unfassbar es klappt! :D

Der Tipp mit dem Kontrast hats gebracht. Muss man auch erstmal drauf 
kommen, dass der Kontrast sich bei den Modi ändert!

Danke Lupin für den Link, aber ich bleibe doch lieber bei C ;)

Die Initialisierung hatte ja auch so schon geklappt und die Funktion 
set_cursor für mehrere Zeilen hab ich mir zurechtgestrickt.

Danke an alle :)

von Benedikt K. (benedikt)


Lesenswert?

Der Lars wrote:
> Der Tipp mit dem Kontrast hats gebracht. Muss man auch erstmal drauf
> kommen, dass der Kontrast sich bei den Modi ändert!

Wenn das Display mit einer Zeile läuft, dann werden 8 Pixelzeilen 
nacheinander angesteuert, jede Pixelzeile ist 1/8 der Zeit an.
Bei 2 Zeilen werden 16 Pixelzeilen angesteuert, jede Pixelzeile ist 
daher nur 1/16 an. Um dennoch die gleiche Spannung an jeden Pixel 
anzulegen, muss die Spannung daher höher sein (etwa um Wurzel 2 wegen 
dem Effektivwert).

von Der L. (vhdl-neuling)


Lesenswert?

@Benedikt

Danke für die Erklärung, das leuchtet ein! :)

Hätte noch eine weite LCD-Frage und weiß nicht ob ich extra nen neuen 
Thread öffnen soll.

Wenn ich eine Variable ausgeben möchte, gibt er mir ja mit LCD_data(var) 
den ASCI-Code des Wertes der Variablen aus. Aber was muss ich tun, damit 
das Display mir den wirklichen Wert ausgibt?

Danke,
derLars

von Dieter E. (netdieter) Benutzerseite


Lesenswert?

Such mal nach sprintf()
Das tut den Trick ;-)

von Der L. (vhdl-neuling)


Lesenswert?

Danke für den Hinweis!

Hab mir jetzt etwas zusammen geschustert, aber so ganz funktioniert das 
nicht, wenn das Ergebnis auch hübsche Zeichen zutage bringt.
1
  int test=23;
2
  lcd_var(test);
3
4
void lcd_var(unsigned int temp1)
5
{
6
   int lf;
7
   char eingabe[2];
8
   
9
   LCD_COMMAND_PORT |= 0x01;         // RS auf 1 setzen
10
 
11
   sprintf(eingabe,"%d",temp1);
12
 
13
   for (lf=2;lf>0;lf--){
14
     LCD_PORT = eingabe[lf];               // setzen
15
     lcd_enable();         // übergeben
16
     waitms(10);
17
   }
18
}

Habs wohl doch noch nicht so recht verstanden. :-/

von Dieter E. (netdieter) Benutzerseite


Lesenswert?

Wenn LCD_data(var) bereits den ASCII-Code ausgibt, dann must Du den 
Inhalt der Variable nur noch nach ASCII transformieren.

Also in Etwas so:
1
 int test=23;
2
 char Buffer[128];
3
4
 sprintf( Buffer, "%d", test );
5
 LCD_Data(Buffer);

von Michael (Gast)


Lesenswert?

Versuchs mal so,

sprintf(&eingabe[0],"%d",temp1);

So wie ich das gelernt hab ist eingabe[2] ein Array.Wenn du was rein 
schreiben möchtest, musst du mit einem Zeiger auf die Stelle verweisen 
an der du mit dem schreiben beginnen möchtest.

&eingabe[0] = ein Zeiger auf die stelle 0 des Arrays eingabe[2]

von Benedikt K. (benedikt)


Lesenswert?

Michael wrote:

> &eingabe[0] = ein Zeiger auf die stelle 0 des Arrays eingabe[2]

Ob eingabe oder &eingabe[0] ist egal, denn beides ist ein Zeiger auf den 
Anfang des Arrays.

von Der L. (vhdl-neuling)


Lesenswert?

Danke Dieter :)

lcd_data macht es nicht, aber wie im Tutorial funktioniert lcd_string 
damit.

Gruß vom Lars

Nachtrag: Und danke dem Rest :o)

von Karl H. (kbuchegg)


Lesenswert?

Der Fehler dürfte gewesen sein, dass du hier
1
void lcd_var(unsigned int temp1)
2
{
3
   int lf;
4
   char eingabe[2];

Das Array eingabe viel zu klein dimensioniert hast.
Das String Array hat eine Länge von 2 Elementen. Jeder C-String wird mit 
einem 0-Byte abgeschlossen. Das wiederrum bedeutet, dass deine Zahl in 
temp1 nur 1-stellig sein darf, weil du ja im Array nur Platz für 1 
Zeichen hast.

An solchen Stellen ist falscher Geiz absolut kontraproduktiv.
Ein unsigned int kann Werte bis 65536 annehmen. Das sind 5 Stellen. Du 
brauchst also als minimale Arraygröße 6 (wegen dem abschliessenden 
0-Byte).
Aber nicht kleckern, klotzen. Gib dir noch ein paar Bytes Reserve dazu 
...
1
void lcd_var(unsigned int temp1)
2
{
3
   int lf;
4
   char eingabe[64];

... denn irgendwann machst du folgendes:
1
     sprintf( eingabe, "Ausgabewert: %d V", temp1 );

und dann sind deine maximal 5 möglichen Zeichen in Eingabe schon wieder 
zuwenig und du suchst dir einen Wolf, wo der Fehler liegt.

Auch mal einen Blick auf snprintf werfen.

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.