Hallo Forum,
habe das Forum abgescannt und viele Vorschläge getestet, aber leider
nicht erfolgreich. Nutze Atmel Studio 7.0, die LCD und I2C Haeder- und
C-Dateien von Peter Fleury mit einem Atmega 328P mit 16 MHz. Habe bisher
ein 2x16 Display genutzt. Alles funktioniert einwandfrei. Habe mir jetzt
mehrer 4x20 Displays gekauft. In den Headerdateien die defines auf 4
Zeilen und 20 Spalten und die Zeilenadressen angepasst. Funktioniert
bedingt, die Zeilendarstellung bekomme ich nicht hin. Mir ist bekannt,
das die Zeile 1 in Zeile 3, respektive Zeile 2 in Zeile 4 fortgesetzt
wird. Das funktioniert auch einwandfrei. Ich möchte aber nach einem
"lcd_print nextline()" eine neue Zeile nutzen. Nach Zeile 1 klappt es,
da die Zeilenadresse für Zeile 2 0x40 wohl übernommen wir. Habe mehrer
Vorschläge für die Zeilen wie z.B. 0x00, 0x40, 0x14, 0x54 getestet.
lcd_print nextline wird ab Zeile 2 nicht angenommen.
Ich habe im Datenblatt des 2004A gesehen, dass als LCD Controller ein
ST7066U verbaut ist. Ist u.U dieser Baustein nicht kompatibel mit HD
44870 etc.
Das LCD enthält einfach nur einen großen Buffer in den dies strings (als
ASCII) reingschrieben werden. Das nextline macht deine library im
hintergrund.
Solange wir die nicht kennen ist alles nutzlos....
Heinz W. schrieb:> Ich habe im Datenblatt des 2004A gesehen, dass als LCD Controller ein> ST7066U verbaut ist. Ist u.U dieser Baustein nicht kompatibel mit HD> 44870 etc.
Hi,
habe 2 x 16 LCDs mit KS0066U-(ST7066)
selber getestet.
Kein Unterschied.
Was vielleicht etwas anders sein kann, sind die
Befehlsausführungszeiten und die Pausen zwischen den
einzelnen Schritten gerade bei der Initialisierung.
Und wenn es ein 40-er sein sollte, der zwei Controller hätte,
dann müsstest Du auch 2 Enable Anschlüsse haben.
Und entsprechend 2x Enableimpuls senden (jeweils einen auf den
jeweiligen Pin.)
Ist aber wohl nicht so.
Wie sieht deine Befehlsfolge zu "locate" aus?
Bei mir:
Schnipsel in ASM.
Wobei zwei Routinen drin sind.
Einmal Befehl auf LCD
dann Charakter auf LCD
Die kennst Du bestimmt schon, brauche ich hier nicht ausführen.
Die Anfangsadressen findest Du doch durch Addition raus.
Schau Dir das Dabla für die Funktionsaufrufe einmal daraufhin an.
ciao
gustav
Heinz W. schrieb:> Habe mir jetzt> mehrer 4x20 Displays gekauft. In den Headerdateien die defines auf 4> Zeilen und 20 Spalten und die Zeilenadressen angepasst.
Das reicht u.U. nicht. Welche Library ist es denn? Es gibt ja nur ca.
hundert verschiedene ...
> Funktioniert bedingt, die Zeilendarstellung bekomme ich nicht hin.
Großartige Fehlerbeschreibung!
> Mir ist bekannt,> das die Zeile 1 in Zeile 3, respektive Zeile 2 in Zeile 4 fortgesetzt> wird. Das funktioniert auch einwandfrei. Ich möchte aber nach einem> "lcd_print nextline()" eine neue Zeile nutzen.
Ja, dann machs halt. Der Code für die Behandlung des NEWLINE Zeichens
muß die aktuelle Zeile anschauen und basierend darauf die
Schreibposition und die (neue) aktuelle Zeile setzen. Für ein 4-Zeilen
Display brauchst du also eine Kette aus 4 if() Statements. Irgendwo da
hast du einen Fehler drin. Zeig den Code!
Versuche mal
#define LCD_LINE1 0x00
#define LCD_LINE2 0x38
#define LCD_LINE3 0x14
#define LCD_LINE4 0x54
oder
#define LCD_LINE1 0x00
#define LCD_LINE2 0x38
#define LCD_LINE3 0x28
#define LCD_LINE4 0x48
Das sind Werte die ich früher bei 20x4 Displays verwendet hatte.
Bei mir sehen die Adressen anders aus:
Siehe Bild.
Ist I2C über USI Krücke.
Funktioniert aber.
Ob das I2C ist oder sonstwas, (über den PIC Adapter):
die Startadressen sind LCD-spezifisch.
https://bin-dez-hex-umrechner.de/Max D. schrieb:> Das LCD enthält einfach nur einen großen Buffer in den die strings (als> ASCII) reingeschrieben werden.
Immer alternierend addieren:
in Dezimal:
128
192
148
212
Wieso das so ist, liegt am Displaycontroller.
Frag mich nicht, der Hersteller hat sich da was gedacht.
Vermutung:
Es werden für verschiedene "Längen" eben dieselben Controller verwendet.
Und da gibt es eben "Lücken", weil nicht alles was adressierbar wäre,
auch angezeigt werden kann.
Z.B. bei einem 2 x 16 die restlichen 4 Stellen fehlen.
Dafür gibt es aber keine "Extrawurst".
ciao
gustav
Karl B. schrieb:> Frag mich nicht, der Hersteller hat sich da was gedacht.
Das liegt unter anderem daran, das es einen Expanderchip für den alten
HD44780 gibt, den HD44100. Der hängt als Unterling am 44780 und füllt
die fehlenden Speicheradressen. (Gut, es ist ein wenig komplizierter,
aber das Prinzip ist so).
Du hast doch fast alle notwendigen Werte schon gefunden...
Heinz W. schrieb:> Ergebnis:>> Display Zeile 1:Zeile 1:XXXXXXXXXXXX> Display Zeile 2:Zeile 4:UUUUUUUUUUUU> Display Zeile 3:> Display Zeile 4:Zeile 3:ZZZZZZZZZZZZ>> Display Konfiguration in i2clcd.h>> #define LCD_I2C_DEVICE 0x4E> #define LCD_LINES 4> #define LCD_COLS 20> #define LCD_LINE_MODE LCD_4LINE>> #define LCD_LINE1 0x00> #define LCD_LINE2 0x40> #define LCD_LINE3 0x15> #define LCD_LINE4 0x54
Zeile 1 erscheint mit richtigem Inhalt an der gewünschten Position.
Also ist #define LCD_LINE1 0x00 richtig.
In Zeile 2 erscheint der Inhalt für Zeile 4.
Also änderst du LCD_LINE4 von 0x54 auf 0x40.
In Zeile 4 kommt der Inhalt für Zeile 3.
Also wird LCD_LINE3 zu 0x54.
Fehlt noch die Zeile 2. 0x15 ist mit Sicherheit falsch. Sinnvoller wäre
0x14 (20 Zeichen Versatz). Macht als Tabelle:
#define LCD_LINE1 0x00
#define LCD_LINE2 0x14
#define LCD_LINE3 0x54
#define LCD_LINE4 0x40
Heinz W. schrieb:> lcd_command(LCD_HOME);> lcd_print("Zeile 1:XXXXXXXXXXXX");> lcd_nextline();> lcd_print("Zeile 2:yyyyyyyyyyyy");> lcd_nextline();> lcd_print("Zeile 3:ZZZZZZZZZZZZ");> lcd_nextline();> lcd_print("Zeile 4:UUUUUUUUUUUU");
Das halte ich generell für grenzwertig. Die (uralte) Fleury-Lib die ich
hier in einem Projekt verwende, hat ein Konfigurationsflag
LCD_WRAP_LINES (defaultmäßig aktiv) und schaltet am Ende einer Zeile
automatisch auf die nächste Zeile. Da du oben immer 20 Zeichen ausgibst,
wären in diesem Fall die Aufrufe von lcd_nextline() komplett unnötig.
Und ganz generell würde ich da eher lcd_gotoxy() verwenden.
> Display Konfiguration in i2clcd.h>> #define LCD_LINE1 0x00> #define LCD_LINE2 0x40> #define LCD_LINE3 0x15> #define LCD_LINE4 0x54
Wenn du nicht gerade ein ganz und gar exotisches Display hast, dann
müßte das so aussehen:
#define LCD_LINE1 0x00
#define LCD_LINE2 0x40
#define LCD_LINE3 0x14
#define LCD_LINE4 0x54
Wenn ich bei einem Display nicht sicher bin, dann fülle ich einfach mal
das Display-RAM mit dem ASCII (oder was das Display dafür hält)
Zeichensatz. In einer Schleife mit ein paar 100ms Pause nach jedem
Zeichen. Da sieht man dann sehr gut, welche Zeile welcher Adresse
entspricht.
Max D. schrieb:> Das nextline macht deine library im> hintergrund.> Solange wir die nicht kennen ist alles nutzlos....Axel S. schrieb:> Das reicht u.U. nicht. Welche Library ist es denn? Es gibt ja nur ca.> hundert verschiedene ...
?
Heinz W. schrieb:> die LCD und I2C Haeder- und> C-Dateien von Peter Fleury mit einem Atmega
ich zeige sie euch, muss schwer sein ;)
http://www.peterfleury.epizy.com/avr-software.htmlAxel S. schrieb:> Wenn ich bei einem Display nicht sicher bin, dann fülle ich einfach mal> das Display-RAM mit dem ASCII (oder was das Display dafür hält)> Zeichensatz. In einer Schleife mit ein paar 100ms Pause nach jedem> Zeichen. Da sieht man dann sehr gut, welche Zeile welcher Adresse> entspricht.
genauso, oder in die LIB schauen und passend machen, sehe da auch keine
Probleme.
Habe mit der Fleury LIB auch angefangen, sehr gut zu verwenden unter AVR
oder Arduino(Atmel AVR) wer keine anderen findet.
Schreibe doch einfach alle Buchstaben von A-Z und von a-z ab der
DD-RAM-Adresse 0 aufs Display. Dann kannst Du einfach ausrechnen, wo die
weiteren Zeilen beginnen. Wenn Du dann noch nichts in einer Zeile
siehst, setzte voher den Cursor auf 0x20, 0x30 oder 0x40 und probiere es
noch mal.
In dem Datenblatt für ein 4x20 display ist die Rede von einem "1-line
mode" mit linearen Adressen von 0x00-0x4F (0-79), sowie ein "2-line
mode" mit Adressen von 0x00-0x27 Zeile 1 (und vermutlich nahtloser
Übergang in Zeile 3) und 0x40-0x67 für Zeile 2 (weiter in 4).
https://www.beta-estore.com/download/rk/RK-10290_410.pdf
Was bei diesen Speicherorganisationen dann nicht geht ist scrollen des
Display-Inhaltes.
Edit: nicht CG-RAM sondern DD-RAM Adresse. CG ist der Speicher zum
definieren eigener Sonderzeichen.
Hi,
ist der Unterschied von 2004 zu 2004A
so groß?
Oben sind die Anfangs-Adressen des SainSmart2004
schon einmal angegeben worden.
Beitrag "Re: LCD 4x20 2004A auf Zeilen schalten"
Könnte man doch einmal ausprobieren, oder?
ciao
gustav
Hallo Forum -- ich bin schon fast verzweifelt--
habe in der Zwischenzeit alle?? Vorschläge zur 4 Zeilen Darstellung auf
dem Display 2004A mit I2C Interface (LCD und I2C Haeder- und
C-Dateien von Peter Fleury) ausprobiert. Leider funktioniert es nicht.
Habe ein weiteres Display nach dem AVR-GCC-Tutorial/LCD-Ansteuerung
vorbereitet und siehe da, alles funktioniert wunschgemäß.
Bei der I2C Anbindung und der 4 Zeilen Konfiguration erhalte ich bei
folgender Sequenz:
lcd_gotolc(1,5);
lcd_print("12345");
lcd_gotolc(1,30);
lcd_print("ABCD");
lcd_gotolc(2,8);
lcd_print("56789");
lcd_gotolc(2,85);
lcd_print("EFG");
Das im Bild dargestelle Ergebnis. Die Zeilenadressen habe ich die aus
dem Programm s.o. übernommen. Bei erhärtet sich der Eindruck, dass durch
i2clcd.c der gewünschte Modus vom Display nicht umgeschaltet wird. Für
einen Tipp oder erprobte Routine wäre ich dankbar.
MfG
Heinz
Bitte probier das folgende Programm aus und zeige uns die Ausgabe:
(ich kenne nicht den Namen deiner Funktion, die nur ein Zeichen ausgibt,
ich nenne sie mal lcd_lcd_char)
char i;
lcd_initialisieren(); (heisst bei dir bestimmt anders)
lcd_gotolc(1,1);
for (i = 0x21; i < 0x72; i++) {
lcd_lcd_char(i);
}
Das sollte dir das gesamte Display voll schreiben.
lcd_gotolc(1,5);
lcd_print("12345");
Die nächste Schreibposition ist 10.
lcd_gotolc(1,30);
In Zeile1 gibt es keine Pos.30! Die Funktion wird nix tun.
lcd_print("ABCD");
Hier wird nun ab Pos10 weitergeschrieben.
Ändere die 30 auf 18.
Vllt. das hier mal ausprobieren!
#define LCD_LINE1 0x00
#define LCD_LINE2 0x20
#define LCD_LINE3 0x40
#define LCD_LINE4 0x60
Sind zwar Adressen für einen KS0073 aber mal probieren.
Schau bitte auch mal ins Datenblatt ob ein sog.
Erweiterungs Bit RE, für Sonderfunktionen (Function Set)setzen musst zum
Umschalten in den 4 Bit Modus.
Ich hatte vor kurzem auch ein Problem mit der LCD-Library von Peter
Fleury bei 16 MHz. Ich vermute ein Timing-Problem mit der internen
delay-Funktion. Ich meine, etwas in der Library von 4 Mhz gelesen zu
haben. Eventuell liegt hier die Herausforderung!?
Das meine ich:
[c]
/***********************************************************************
**
delay for a minimum of <us> microseconds
with a 4Mhz crystal, the resolution is 1 us
************************************************************************
*/
static void delay(uint16_t us)
{
while ( us ) us--;
}
[-c]
Bei 16 MHz sind das dann keine 1µs Wartezeit.
Hugo H. schrieb:> #define F_CPU 16000000UL (falls nicht im Projekt eingetragen)
Das hilft aber nicht der internen delay-Funktion. Die wird nicht von
dieser Einstellung korrigiert. In meinem Projekt reagierte das Display
bei Clear, Home und GotoXY seltsam.
BlaBla schrieb:> Das meinte ich:> /*********************************************************************** **> delay for a minimum of <us> microseconds> with a 4Mhz crystal, the resolution is 1 us> ************************************************************************ */> static void delay(uint16_t us)> {> while ( us ) us--;> }>> Bei 16 MHz ist das dann keine 1µs Wartezeit.
Und die Funktion wird auch noch im AS7 (-O1) weg optimiert.
BlaBla schrieb:> static void delay(uint16_t us)> {> while ( us ) us--;> while ( us ) us--;> while ( us ) us--;> while ( us ) us--;> }
Möchtest du das bitte noch einmal überlegen?
Hinweis: Welchen Wert hat us nach dem ersten while?
Hallo und guten Tag,
habe mein Problem gelöst. Das Display 2004A funktioniert mit dem I2C
Modul
jetzt einwandfrei. Ich denke der Compiler hat mir die Sorgen bereitet.
Habe die Optimierung in AS 7.0 auf "Optimize for size (-Os) gestellt.
Konnte allerdings noch nicht ermitteln was wegoptmiert wurde. Betreibe
den Atmega 328P nach wie vor mit 16 MHz und die I2C Schnittselle mit 1
kHz. Meine
Zeilenadessen sind 0x00, 0x40, 0x14 und 0x54.
Ich bedanke mich für alle Beiträge zur Lösung meiner Problematik. Da ich
schon etwas älter bin (Jahrgang 1943) und keine externe Hilfe habe, muss
ich mir Unterstützung in den Foren suchen. Ist wieder einmal sehr gut
gelungen.
Danke!!
MfG
Heinz
Ob jetzt noch die 1 µs stimmen?!? War jetzt mal quick & dirty.
Heinz W. schrieb:> habe mein Problem gelöst.
Den Optimierer auszuschalten ist trotzdem blöd. Der wird von
<util/delay.h> benötigt. Ich wollte jetzt auch nicht zuviel in Peters
Lib ändern. Aber schön das es läuft.