Hab ein Problem mit einem Pollin LCD Dot Matrix 2 x 20 Display. Ich sende dem Ding 3 mal 0x03, dann ein 0x02 (4 Bit Modus), dann ein 0x28 und dann ein 0x0F, jetzt sollte der Cursor blinken und auf der ersten Stelle stehen oder ? Jas manchmal macht er das auch, nur dann nehm ich die Spannung weg, dann macht er das nicht mehr. Dann Spiel ich den Code neu rein, dann macht er es manchmal und manchmal auch nicht... Ich bin am verzweifeln... hatte noch nie Probleme mit den Displays von Reichelt
Und ich lass ihm meines Erachtens genug Zeit. 100 ms Warmup und dann zwischen den Enable Pulsen 1 ms
Matthias wrote: > Und ich lass ihm meines Erachtens genug Zeit. 100 ms Warmup Das kann gelegentlich zu wenig sein. Ich nehme meist 500 ms. > und dann > zwischen den Enable Pulsen 1 ms Das muss reichen. ...
LCD Display ist genauso unsinnig wie HIV Virus es heisst doch schon liquid crystal display
"Gast" ist genauso unsinnig wie "Besucher". Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen. Das Display wird ja nur beim Programmstart initialisiert, da kann man auch mal eínen Moment warten. MfG Paul
gast wrote: > LCD Display ist genauso unsinnig wie HIV Virus > es heisst doch schon liquid crystal display Wir wissen es... ...
Paul Baumann wrote: > "Gast" ist genauso unsinnig wie "Besucher". Das ist wohl wahr... > Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen. Nagut, ich nur vor dem ersten Init-Kommando. > Das Display > wird ja nur beim Programmstart initialisiert, da kann man auch mal eínen > Moment warten. Nein, warten??? Niemals nie nicht. Man muss unbedingt die höchstmögliche Taktfrequenz benutzen, oder besser noch übertakten, und dann überall das Timing hart am Limit dimensionieren. Höher, schneller, weiter, nix für Weicheier oder Warmduscher... ;-) > > MfG Paul ...
gast wrote: > LCD Display ist genauso unsinnig wie HIV Virus > es heisst doch schon liquid crystal display Und ich dachte immer, es heisst "Liquid Crystal Device" ....
Um mal wieder zum Thema zu kommen: Um welches Display geht es denn (gibt ja derer zwei bei Pollin...). Sven
Ich kenn zwar das Datenblatt des Pollin-Displays nicht, aber die Ansteuerung von Characterdisplays ist quasistandardisiert. Fehlermöglichkeiten gibt es viele : Bei der Initialisierung müssen diese Einstellungen passen : - die R/W-Leitung auf Low - die Command/Data-Leitung auf Low - die Enable-Leitung benötigt einen High-Impuls für Datenübernahme Ansonsten ist ein beliebter Fahler, dass die Datenleitungen verdreht sind (MSB vs. LSB).
>Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen.
Das würde ich mal lassen, es gibt Displays, die habens nicht gern wenn
sie mit der initialisierung ewig warten müssen....
Ich verwende eigentlich die Funktionen wie hier im Forum beschrieben, nur sind meine Datenports nicht an einem Port des Atmels sondern einer auf PORT C0 und die anderen auf Port D7 6 und 5. Somit habe ich folgende Umformung programmiert die wahrscheinlich nicht funktioniert. Kann da mal einer drüberschauen. void LCD_write_in_ports(unsigned char data) { unsigned char i = 0, data_temp=0; cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); while(i < 4) { data_temp = data; if(i == 0) data_temp &= 0x01; if(i == 1) data_temp &= 0x02; if(i == 2) data_temp &= 0x04; if(i == 3) data_temp &= 0x08; if((data_temp) && (i == 0)) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); else if((data_temp) && (i == 1)) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); else if((data_temp) && (i == 2)) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); else if((data_temp) && (i == 3)) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); i++; } }
> if((data_temp) && (i == 0))
Die Abfrage ist falsch. Da werden alle Bits von data_temp
berücksichtigt.
if((data_temp & 0x01) && (i == 0))
Allerdings kannst du ne Menge Code sparen wenn du keine Schleife nimmst
;)
>Die Abfrage ist falsch. Da werden alle Bits von data_temp >berücksichtigt. Quatsch meinerseits natürlich. Zum zweiten Teil steh ich aber noch.
Jetzt bin ich verwirrt. Ist die Funktion jetzt falsch bzw. arbeitet sie richtig oder gibt es einen Logik Fehler. Diese Funktion ist essentiell für mich, da Sie die 4 Data Ports mit den gewünschten Zuständen speist.
Sieht schon richtig aus, wenn auch umständlich programmiert. Kleiner Tip: cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
Mache ich vielleicht bei der Initialsiserung etwas falsch wenn ich folgende Kombination schicke. 1.) 500 ms warten 2.) 3 mal 0x03 senden mit 10 ms Pause (RS Low) 3.) 0x02 senden 4.) 0x28 senden 5.) 0x0F senden 6.) 0x06 senden 7.9 LCD_clear(); aus. Ich habe ein 2x16 Zeichen Display von Pollin mit Blauem Hintergrund. R/W liegt auf Masse.
Die erste Zeile wird immer mit schwarzen Kästchen gefüllt. Die Initialsierung klappt dann nicht oder. Hat keiner Erfahrung mit dem Display, was mach ich falsch
Matthias wrote: > Die erste Zeile wird immer mit schwarzen Kästchen gefüllt. Hmmm... Schwarze Kästchen beim blauen LCD? > Die > Initialsierung klappt dann nicht oder. Die pixelaktivierte erste Zeile ist ein Zeichen dafür, dass das LCD seinen Selbsttest überstanden hat, dass Spannung anliegt und der Kontrast halbwegs vernünftig eingestellt ist, dass aber noch keine Initialisierung vom Programm erfolgt ist. Das kann folgende Ursachen haben (kein Anspruch auf Vollständigkeit): - Anschlüsse vertauscht - zu geringe Wartezeit vor dem ersten Zugriff - falsches Timing zwischen den Zugriffen - fehlerhafte Routinen - Irrtum bei der Dimensionierung der Warteschleifen (Startwerte zu groß für den Datentyp, Abschneiden der oberen Bits aufgrund zu hoher Taktfrequenz) - Irrtum beim Bestimmen der Taktfrequenz - Irrtum bei der Zuordnung LCD zum Datenblatt (einige LCDs gleicher Bauart haben andere Taktfrequenzen, um z.B. Strom zu sparen, laufen sie langsamer) > Hat keiner Erfahrung mit dem > Display, was mach ich falsch Ich besitze dieses LCD nicht, da ich nicht bereit bin, "Blau-Zuschlag" zu bezahlen. Wenn Du mir eins sponserst, schreibe ich Dir einen funktionierenden Treiber für AVR in ASM. Wenn nicht, auch gut, ich komme auch ohne das blaue LCD zurecht, ich habe genug Grüne. ...
>Das kann folgende Ursachen haben (kein Anspruch auf Vollständigkeit):
+ falscher Controller
Könnte auch ein KS066, KS070 oder KS073 sein.
Kaufe kein Display bei Pollin wenn kein vernünftiges Datenblatt
vorhanden ist ;)
Versuch es mal so für KS066
1.) 500 ms warten
3.) 0x02 senden
3.) 0x02 senden
3.) 0x0C senden
5.) 0x0F senden
6.) 0x06 senden
Und noch ein Hinweis : Oben schreibst Du, dass Du das Display im 4-Bit-Modus betreibst. Da liegt die Fehlermöglichkeit der Nibblevertauschung nahe. Eh klar : Zuerst das High-Nibble, dann das Low-Nibble. Zwischen zwei 4-Bit-Zugriffen muss typisch ein Delay von mindestens 40us liegen. Dass Du es bei der Initialisierung in den 4-Bit-Modus bringst, sieht man am Wert 0x28 (Kommando SET FUNCTION).
Ich nehme die Funktionen aus dem Forum, nur schreibe ich mit folgender Funktion cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); die 4 Ports und nict mit PORT_LCD = .... Somit müsste die High und Low Bit Vertauschung ausgeschlossen sein.
falls es ein hd47xxx (oder so ähnlich) ist : hast du die 4 nicht benutzten bits auf einen festen pegel gelegt ? sind es die 4 UNTEREN bits die auf diesem festen pegel liegen ? über die beiden fehler bin ich auch schonmal gestolpert. hat was gedauert bis ichs gefunden habe. seit dem mach ichs IMMER, wenn ich 4 bit mode nutze. ansonsten evtl. mal größeres delay (nachdem du dem display gesagt hast das es auf 4 bit spielen soll)
Die unteren 4 Bits sind offen, haben also keinen definierten Pegel. Bei den Reichelt Displays musste ich das nicht machen ...
>Die unteren 4 Bits sind offen, haben also keinen definierten Pegel.
aua aua ...
das kann (!) die ursache dafür sein. wie gesagt habe einige stunden
damit zugange gebracht genau diesen fehler zu suchen.
bei mir liegen die pins auf masse (obwohl es auch einige displays gibt
die dort einen high pegel erwarten wenn ich mich nicht irre)
quark
>damit zugange gebracht genau diesen fehler zu suchen.
meine : ... diesen fehler zu finden
Kann mir mal einer sagen ob das scheiss Ding nur im 8 Bit Modus geht, oder was ? Ich dreh noch durch... wenn ich das 0x28 sende, springt der Cursor an die fünfte Spalte in der Ersten Zeile und wieder zurück.... Wenn ich aber über 0x0F den Cursor ein und über 0x0C ihn ausschalte geht das...
ich habe irgendiwe das Gefühl das das Tutorial zum LCD hier völlig Sinnlos ist. Offensichtlich schaut eh keiner rein. D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden ja auch auf Low gelegt. Zum Timing:... wäre was für das Tutorial... Ich benutze die Char. Display immer in der Timer ISR. Die läuft konstant mit 6-7ms. Der längste Befehl im 44780 braucht 5,x ms. Alle Befehle werden in der ISR gesendet. Auch das Display wird in der ISR initialisiert und beschrieben. Das Display liegt 1:1 abgebildet im RAM. Man muss in der Main nur den RAM beschreiben und sich sonst und das Display überhaupt nicht kümmern. Die Idee stammt nicht von mir, sondern von Andreas Roth. 8051 Kochbuch. ABER es geht einfach nur. Keine Sorgen mit dem Timing für Anfänger. Profis haben diese Sorgen eh nicht. Also Tutorial lesen, Fusebits beachten, Trimmer für Kontrast prüfen..usw.
> ich habe irgendiwe das Gefühl das das Tutorial zum LCD hier völlig > Sinnlos ist. Offensichtlich schaut eh keiner rein. > D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden > ja auch auf Low gelegt. hab ich gemacht...bringt nichts, hab neben mir eine zweite Schaltung mit einem Reichelt Display Pin 0 - 3 offen und das Ding geht eins a im 4 Bit Modus..soviel dazu Ansonsten beachte ich wirklich alles... Das Scheiss Ding lässt sich einfach nicht korrekt Initialisieren. Jetzt schick ich mal den gesamten Code... *********************************************** #include <avr/io.h> #include "lcd.h" #include "mydefs.h" #include <util/delay.h> // sendet ein Datenbyte an das LCD void LCD_data(unsigned char temp1) { unsigned char temp2 = temp1; LCD_rs_enable(); // RS auf 1 setzen temp1 = temp1 >> 4; temp1 = temp1 & 0x0F; LCD_write_in_ports(temp1); LCD_enable(); temp2 = temp2 & 0x0F; LCD_write_in_ports(temp2); LCD_enable(); _delay_ms(10); } // sendet einen Befehl an das LCD void LCD_command(unsigned char temp1) { unsigned char temp2 = temp1; LCD_rs_disable(); // RS auf 0 setzen temp1 = temp1 >> 4; // oberes Nibble holen temp1 = temp1 & 0x0F; // maskieren LCD_write_in_ports(temp1); LCD_enable(); temp2 = temp2 & 0x0F; // unteres Nibble holen und maskieren LCD_write_in_ports(temp2); LCD_enable(); _delay_ms(10); } // erzeugt den Enable-Puls void LCD_enable(void) { // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16" sbi(LCD_EN_PORT,LCD_EN_NR); _delay_ms(10); // kurze Pause // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern // Beitrag "LCD -> Probleme mit Optimierungsgrad" cbi(LCD_EN_PORT,LCD_EN_NR); } // Initialisierung: // Muss ganz am Anfang des Programms aufgerufen werden. void LCD_init(void) { // Alle LCD PORTS auf Ausgang schalten sbi(LCD_RS_DDR,LCD_RS_NR); sbi(LCD_EN_DDR,LCD_EN_NR); sbi(LCD_DATA_4_DDR,LCD_DATA_4_NR); sbi(LCD_DATA_5_DDR,LCD_DATA_5_NR); sbi(LCD_DATA_6_DDR,LCD_DATA_6_NR); sbi(LCD_DATA_7_DDR,LCD_DATA_7_NR); // muss 3mal hintereinander gesendet werden zur Initialisierung _delay_ms(200); LCD_rs_disable(); /* LCD_command(0x03); LCD_enable(); _delay_ms(100); LCD_enable(); _delay_ms(100); LCD_enable(); */ // 4 Bit Modus aktivieren // LCD_write_in_ports(0x02); LCD_command(0x02); _delay_ms(10); LCD_enable(); // 4Bit 2 Zeilen 5x7 LCD_command(0x28); _delay_ms(10); LCD_enable(); // Display ein Cursor aus kein Blinken LCD_command(0x0F); _delay_ms(10); LCD_enable(); LCD_clear(); // inkrement / kein Scrollen LCD_command(0x06); _delay_ms(10); LCD_enable(); } // Sendet den Befehl zur Löschung des Displays void LCD_clear(void) { LCD_command(CLEAR_DISPLAY); _delay_ms(100); } // Sendet den Befehl: Cursor Home void LCD_home(void) { LCD_command(CURSOR_HOME); _delay_ms(1); } // setzt den Cursor in Zeile y (1..4) Spalte x (0..15) void LCD_set_cursor(unsigned char x, unsigned char y) { unsigned char tmp; switch (y) { case 1: tmp=0x80+x; break; // 1. Zeile case 2: tmp=0xC0+x; break; // 2. Zeile case 3: tmp=0x94+x; break; // 3. Zeile case 4: tmp=0xD4+x; break; // 4. Zeile } LCD_command(tmp); } // Schreibt einen String auf das LCD void LCD_string(char *data) { while(*data) { LCD_data(*data); data++; } } void LCD_rs_enable(void) { sbi(LCD_RS_PORT,LCD_RS_NR); } void LCD_rs_disable(void) { cbi(LCD_RS_PORT,LCD_RS_NR); } void LCD_write_in_ports(unsigned char data) { cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR); if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR); if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR); if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR); }
Vergiss erstmal die Ansteuerung. Setze die Pins der Reihe nach High/Low und überprüfe mit dem Oszi, ob die Pegel korrekt ankommen, und zwar da - und nur da - wo sie sollen. Das heisst auch die Nachbarpins checken. Evtl. ist irgendwo eine kleine Lötbrücke, die sieht man oft kaum.
Sorry no Way !!! "C" ist Chaos in "Clammern" ich vertseh nix davon. Ich schreibe ASM. Ist eben wesentlich einfacher. ABER schwerer zu verstehen. Tut mir Leid, kann ich Dir nicht helfen.
>"C" ist Chaos in "Clammern" >Ich schreibe ASM. Ist eben wesentlich einfacher. So einen Schmarren hab ich selten gelesen.
Stephan Henning wrote: > D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden > ja auch auf Low gelegt. Bei echten TTL eher auf high, weil das deutlich weniger Strom kostete. Aber bei den HD44780&Co LCDs sollte man das ausdrücklich nicht tun, sondern die Dinger offen lassen. Erstens hat der LCD-Controller genau deswegen interne Pullups. Zweitens führt das zum Kurzschluss wenn man Daten liest. Dieser Kurzschlusstrom ist zwar zu gering um Schaden anzurichten, ist aber trotzdem Unsinn.
Matthias, das ganze kann auch ein Reset Problem sein, je nachdem wie der Spannungsverlauf beim Ein- und Ausschalten ist. Ich hatte ein Projekt mit LCD, ohne dass Probleme auftraten. In einem späteren verhielt sich das LCD ähnlich wie Du es beschreibst. Seitdem ich die Spannungsversorgung für das LCD getrennt einschalte (der µC kann die Spannung per Transistor schalten) funktionert es wunderbar. In der Beschreibung zum HD44780 steht, wie die Initialisierung bei "schlechtem" Einschaltvorgang aussehen sollte. Das brachte bei mir keine Besserung. Wie verhalten sich die Displays, wenn Du sie austauscht? Ich meine das Pollin-LCD in die alte Reichelt-Schaltung und umgekehrt? Sag' bescheid, falls Du etwas erreichst.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.