hallo, ich komm mal wieder nicht weiter, habe ein 4x20 Zeichen LCD von reichelt. Datenblatt: Controller & LCD Driver ST7066U-0A-B & ST7065C habe eine einfache kleine LCD bibliothek, habe die Port belegung schon überprüft, an der verdrahtung sollte es nicht liegen, habe auch grob den Kontrast verändert, aber außer das komplette schwarze blöcke auftreten ändert sich nichts. hier mal der kurze code, vllt is da ja schon der fehler drin, bin für jede idee dankbar! #define F_CPU 4000000 #include <avr\io.h> #include <util\delay.h> #include <lcd-neu.h> /* // LCD AUSGABE //lcd_write() sendet eine Zeichenkette an das LCD void lcd_write(char* pText) { while(pText[0]!=0) { lcd_write(pText[0]); pText++; } } */ // Programm main () { DDRD = 0xff; _delay_ms(200); lcd_init(); _delay_ms(20); //lcd_goto(1,1); _delay_ms(20); while(1); { lcd_string("HALLO"); _delay_ms(200); } }
als ergänzung, noch kurz aus der quelle, vllt liegt ja auch hier der fehler.. void lcd_string(char *data) { while(*data) { lcd_data(*data); data++; } }
Es fehlt das Listing von lcd_init(). Da es sich (vermutlich) um ein Initialisierungsproblem handelt, ist das höchst unpraktisch.
hier die initialisierung, void lcd_init(void) { // Ports auf Ausgang schalten LCD_DDR_4 |=(1<<LCD_D4); LCD_DDR_5 |=(1<<LCD_D5); LCD_DDR_6 |=(1<<LCD_D6); LCD_DDR_7 |=(1<<LCD_D7); LCD_EN1_DDR |= (1<<LCD_EN1); LCD_RS_DDR |= (1<<LCD_RS); // muss 3mal hintereinander gesendet werden zur Initialisierung _delay_ms(15); LCD_PORT_4 |= (1<<LCD_D4); LCD_PORT_5 |= (1<<LCD_D5); LCD_PORT_6 &= ~(1<<LCD_D6); LCD_PORT_7 &= ~(1<<LCD_D7); LCD_RS_PORT &= ~(1<<LCD_RS); // RS auf 0 lcd_enable(); _delay_ms(5); lcd_enable(); _delay_ms(1); lcd_enable(); _delay_ms(1); // 4 Bit Modus aktivieren LCD_PORT_4 &= ~(1<<LCD_D4); LCD_PORT_5 |= (1<<LCD_D5); LCD_PORT_6 &= ~(1<<LCD_D6); LCD_PORT_7 &= ~(1<<LCD_D7); lcd_enable(); _delay_ms(1); // 4Bit 2 Zeilen 5x7 lcd_command(0x28); // Display ein Cursor aus kein Blinken lcd_command(0x0C); // inkrement / kein Scrollen lcd_command(0x06); lcd_clear(); }
Dein Code nach while(1); wird nicht aufgerufen, das Semikolon hinter while(1) muss weg! weitehin, ist das ein Tipfehler ??? Du willst mit lcd_string was ausgeben, zeigst aber die Funktion lcd_write und selbst diese ruft sich lediglich selbst auf.
jo, probier das grad mit dem entfernten semikolon aus, das lcd_write ist auskommentiert, sry das ich das aus dem code nicht entfernt habe, melde mich gleich wieder:-)
nur mal als Anmerkung, wenn der Kontrast zu stark ist, d.h. alles schwarz, kann man auf dem Display keine Zeichen erkennen ;-)
Kontrast scheint ok zu sein ist bei etwa 1Volt, daran liegts wohl auch nicht, hab auch leider keine Idee mehr woran das liegen kann das keine reaktion kommt
ich benutze die Lib von P.Fleury , auch im 4bit-Mode. Ist das Display kompatibel zum HD44780-Standard ? Hast Du die Lib selber geschrieben oder aus dem Internet ?
also, ich hab die lib aus dem netz, wenn du mir die lib von p.fleury mal geben könntest wäre das nett, vllt funkts ja. der controller wurde mir von reichelt als kompatibel verkauft, ich verlass mich da mal drauf!
Wenn es ein 44780-kompatibles Display ist (und die meisten Kommandos deuten darauf hin), werden während der ersten 2 E-Pulse falsche Daten gesendet (0x3 statt 0x2). EDIT: Es fehlt auch der Code für lcd_command. Auch dort kann man durchaus was falsch machen.
void lcd_command(unsigned char temp1) { unsigned char temp2 = temp1; LCD_RS_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen temp1 = temp1 >> 4; // oberes Nibble holen temp1 = temp1 & 0x0F; LCD_PORT_4 &= ~(1<<LCD_D4); LCD_PORT_5 &= ~(1<<LCD_D5); LCD_PORT_6 &= ~(1<<LCD_D6); LCD_PORT_7 &= ~(1<<LCD_D7); // maskieren if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ; if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ; if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ; lcd_enable(); temp2 = temp2 & 0x0F; LCD_PORT_4 &= ~(1<<LCD_D4); LCD_PORT_5 &= ~(1<<LCD_D5); LCD_PORT_6 &= ~(1<<LCD_D6); LCD_PORT_7 &= ~(1<<LCD_D7); // unteres Nibble holen und maskieren if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ; if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ; if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ; lcd_enable(); _delay_us(42); }
@ Hc Zimmerer: hast Du Deinen Beitrag nachträglich noch mal geändert, siehe EDIT. wie geht das ?
Zitat während der ersten 2 E-Pulse falsche Daten gesendet (0x3 statt 0x2). versteh leider nicht was du damit meinst, was muss ich ändern, und was ist der fehler? danke für die lib!!!, werde es auch damit testen!
Also die Bitmanipulation, die üben wir nochmal. Es scheint bei Dir systematisch zu sein, dass Du die Bits einzeln löschst und danach einzeln reinklopfst anstelle ein einfaches
1 | LCD_PORT = (LCD_PORT & 0xf) | (temp1 << 4); |
zu machen. Führ Dir mal zu Gemüte, warum das dasselbe wie
1 | LCD_PORT_4 &= ~(1<<LCD_D4); |
2 | LCD_PORT_5 &= ~(1<<LCD_D5); |
3 | LCD_PORT_6 &= ~(1<<LCD_D6); |
4 | LCD_PORT_7 &= ~(1<<LCD_D7); // maskieren |
5 | |
6 | if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen |
7 | if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ; |
8 | if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ; |
9 | if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ; |
ist. Aber bring' erst mal die Initilisierung in Ordnung (indem Du 3 statt 2 reinschreibst, wird auf 8 Bit statt 4 Bit gestellt).
Dirk A. schrieb: > während der ersten 2 E-Pulse falsche Daten > gesendet (0x3 statt 0x2). Dieser Teil:
1 | LCD_PORT_4 |= (1<<LCD_D4); |
2 | LCD_PORT_5 |= (1<<LCD_D5); |
3 | LCD_PORT_6 &= ~(1<<LCD_D6); |
4 | LCD_PORT_7 &= ~(1<<LCD_D7); |
5 | |
6 | LCD_RS_PORT &= ~(1<<LCD_RS); // RS auf 0 |
7 | lcd_enable(); |
8 | |
9 | _delay_ms(5); |
10 | lcd_enable(); |
der Initialisierung legt die Zahl 3 an Deinen 4-Bit-Bus und toggelt dann zweimal Enable. Damit stellst Du jeden 44780-kompatiblen Controller auf 8-Bit-Daten, hast aber nur 4.
also, danke fürs erklären, aber, hoffe habs nicht falsch verstanden, ich möchte das LCD im 4 bit modus betreiben, und die libary is wie geschrieben aus dem netz, außerdem is die so angelegt das ich die benutzten ports ganz einfach ändern kann, deshalb wird denke ich jedes bit einzeln maskiert! so, und jetzt du, liege ich falsch? ich hoffe nicht, sonst sind meine c-probleme größer als ich dachte...
also muss ich diese zeile ändern? LCD_PORT_4 |= (1<<LCD_D4); in LCD_PORT_4 &= ~(1<<LCD_D6); ist das richtig?
LCD_PORT_4 |= (1<<LCD_D4); LCD_PORT_5 |= (1<<LCD_D5); LCD_PORT_6 &= ~(1<<LCD_D6); LCD_PORT_7 &= ~(1<<LCD_D7); ergibt 0011 d.h. 3
Nein, Du liegst nicht falsch. Wenn benachbarte Bits des LCD-Datenbusses nicht auf benachbarten Pins eines Ports liegen, ergibt die Bitklopferei Sinn. Wenn's im Layout wirklich sehr knapp zugeht, kann das mal ganz ausnahmsweise sogar angehen. Das mit dem 4-Bit-Modus habe ich schon verstanden. Dein Problem ist: Du initialisierst auf 8 Bit (besagte und von mir oben zitierte 3).
Dirk A. schrieb: > LCD_PORT_4 |= (1<<LCD_D4); > in > LCD_PORT_4 &= ~(1<<LCD_D6); > > ist das richtig? Ja.
wahnsinn, da funtioniert was! ich dank dir dafür vielmals, schön das die lib als 4-bit modus beschrieben ist... so, muss dann nur noch testen ob ich alle 4 zeilen angesprochen bekomme, und meine ursprünglichen ports auch funktionieren. vielen dank nochmals für die gute und schnelle hilfe
so, langsam ist es zum verzweifeln, habe etwas rumprobiert, nichts hat funktioniert, und bin nun zum ausgangspunkt zurückgekehrt, und es funktioniert trotzdem nix, vorhin gings aber noch, hab in der bibliothek nichts weiter geändert, nur den code, wo is der fehler? #define F_CPU 4000000 #include <avr\io.h> #include <util\delay.h> #include <lcd-neu.h> // Programm int main (void) { _delay_ms(200); lcd_init(); _delay_ms(200); while(1) { lcd_string("HALLO"); _delay_ms(200); } }
Dirk A. schrieb: > so, langsam ist es zum verzweifeln, habe etwas rumprobiert, nichts hat > funktioniert, und bin nun zum ausgangspunkt zurückgekehrt, und es > funktioniert trotzdem nix, vorhin gings aber noch, hab in der bibliothek > nichts weiter geändert, nur den code, wo is der fehler? Wahrschinlich immer noch in der lcd-init Funktion Noch ein Hinweis: 'funktioniert nix' ist so ziemlich die nichtssagende Fehlermeldung, die man sich vorstellen kann. Bei einem LCD ist interessant: Sind in der 1ten bzw. 3ten Zeile schwarze Balken? Wenn ja, dann ist die Initialisierung fehlerhaft. Verschwinden die Balken, dann klappt zumindest mal höchst wahrscheinlich die Initialisierung. D.h. aber auch. Wenn du Probleme mit einem LCD hast, dann gib zumindest an, ob du die Balken noch siehst oder nicht. Das gibt den Helfern einen Anhaltspunkt, in welche Richtung gesucht werden muss.
also, das lcd zuckt nicht nach dem einschalten, auch nicht nach einer gewissen zeit! die erste und dritte zeile sehen gleich aus, und unterscheiden sich nur ganz gering, also kaum wahrnehmbar von zeile 2 und 4. schwarze balken sind für mich zu keinem zeitpunkt deutlich sichtbar, wenn man ganz genau hinschaut erkannt man unterschiedliche helligkeiten. und mit der Initialisierung, es funktionierte ja, und dann funkt es mit dem gleichen code aufeinmal nicht mehr... warum?
ich hab das programm mal debuggt, und der debugger bleibt in dieser zeile hängen: LCD_EN1_PORT &= ~(1<<LCD_EN1); ich versteh leider nicht was in dieser Zeile passieren soll. Hier noch der komplette code in dem die Zeile steckt, er wird in der lcd-init aufgerufen! void lcd_enable(void) { // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16" LCD_EN1_PORT |= (1<<LCD_EN1); _delay_us(1); // kurze Pause // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern // Beitrag "LCD -> Probleme mit Optimierungsgrad" LCD_EN1_PORT &= ~(1<<LCD_EN1); }
Dirk A. schrieb: > also, das lcd zuckt nicht nach dem einschalten, auch nicht nach einer > gewissen zeit! > die erste und dritte zeile sehen gleich aus, und unterscheiden sich nur > ganz gering, also kaum wahrnehmbar von zeile 2 und 4. schwarze balken > sind für mich zu keinem zeitpunkt deutlich sichtbar, wenn man ganz genau > hinschaut erkannt man unterschiedliche helligkeiten. und mit der > Initialisierung, es funktionierte ja, und dann funkt es mit dem gleichen > code aufeinmal nicht mehr... warum? Die Beschreibung ist für mich nicht wirklich klar. Was ist, wenn du das LCD ohne µC einschaltest. Dann müssen die Balken klar und deutlich sichtbar sein (damit du einen Anhaltspunkt hast, wie das aussehen muss). Der 2te Teil deiner Beschreibung lässt in mir den verdacht aufkommen, dass deine Kontrasteinstellung nicht stimmt. Das kann man ganz gut kontrollieren, wenn man das LCD alleine einschaltet.
Dirk A. schrieb: > ich hab das programm mal debuggt, und der debugger bleibt in dieser > zeile hängen: > LCD_EN1_PORT &= ~(1<<LCD_EN1); > ich versteh leider nicht was in dieser Zeile passieren soll. Das ist jetzt aber nicht dein Ernst. Wenn du dich selber an einem LCD Treiber Code versuchst, dann darf das keine Schwierigkeiten machen. Das ist eine Standardversion von: Das Bit LCD_EN1 am Port LCD_EN1_PORT auf 0 setzen. So was musst du auf Anhieb erkennen, wenn du kopfüber von einem Baum hängst, mit Honig eingeschmiert und Ameisen auf dir krabbeln. Ein Blick muss genügen. > void lcd_enable(void) > { > LCD_EN1_PORT |= (1<<LCD_EN1); Bit auf 1 > _delay_us(1); // kurze Pause Bischen warten > LCD_EN1_PORT &= ~(1<<LCD_EN1); und Bit wieder auf 0 In Summe wird ein 1-Puls mit einer Länge von 1µs erzeugt.
also, hab den kontrast jetzt so, das anfangs schwarze balken sind. die gehen aber nicht weg, wenn ich manuel den µC nochmal resete funktionierts...manchmal! das ist für mich nicht durchschaubar. klingt für mich, als ob bei der initialisierung manchmal was schief geht! habt ihr dazu nochmal eine idee??
am Anfang des Programms eine kleine Wartezeit einlegen. Gib dem µC auf dem LCD Zeit, sein eigenes Programm hochzufahren ehe du ihn das erste mal ansprichst.
ich habs auch schon mit ner warteroutine versucht: for(x=0;x<50;x++) { _delay_ms(16); } problem ist trotzdem das gleiche!
Display ist im Moment an PORTD, soll später mal an PORTC, aber erst wenns hier richtig funktioniert
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.