Hallo Forumgemeinde, also ich versuche jetzt seit 2 Tagen mein Display anzusteuern. Ich weiß dass es funktioniert da ich es mit CodeVision bereits angesteuert habe. Ich arbeite aber auch ab und zu mit einer anderen Software (IAR). Also muss ich eine eigene C- Datei schreiben. Ich sehe dass natürlich auch mal als eine gute Übung da ich nicht wirklich der Programmierprofi bin. Ich bekomme das aber irgendwie nicht richtig hin da mir einiges an Grundwissen fehlt. Ich habe das PDF für den KS0073 gelesen. Darin steht für den 4 Bit Mode: (S.59) Function Mode: 0x20 Das verstehe ich ja noch da ja mit dem DB4 = 0 in den 4 Bit Mode gewechselt wird. Im Beispiel wird aber nur ein Nibbel gesendet, wie so dass den?? Sonst benötige ich doch immer 2 Nibbel. Wie weiß den das Display das jetzt noch ein Nibbel kommt oder nicht?? Mein Quellcode sieht so aus: /////// lcd.h///////////// #define LCD PORTC #define LCD_D DDRC #define RS 0 // Bit[0] --> Umschalten zwischen: Befehl(Low) und Daten (High) #define RW 1 // Bit[1] --> Unschalten zwischen: Write (Low) und Read (High) #define EN 2 // Bit[2] --> Enable bei fallender Flanke void pause(int zaehler) { int temp=zaehler; while(temp>0) { asm ("nop"); asm ("nop"); temp--; } } void toggel_en() { pause(10000); LCD|=(1<<EN); //RS Pin auf High pause(10000); LCD&=~(1<<EN); //RS Pin auf Low pause(10000); } void send_to_lcd(U8 daten) { LCD = (daten&0xf0); // das erste Nibbel der Daten auf die 4 Datenleitungen legen toggel_en(); // EN "toggeln" --> high / low LCD = (daten<<4); // das zweite Nibbel der Daten auf die 4 Datenleitungen legen toggel_en(); // EN "toggeln" --> high / low } lcd_init() { pause(20000); // länger Zeit warten //Port A als Ausgang LCD_D=0xff; LCD=0x00; LCD &= ~ (1<<RS); // RS auf low LCD &= ~ (1<<RW); // RW auf low send_to_lcd(0x20); // schaltet in den 4 Bit Modus pause(20000); // länger Zeit warten send_to_lcd(0x24); // RE = 1 send_to_lcd(0x0B); // 5 DOT, normal cursor, 4 Lines send_to_lcd(0x20); // RE = 0 send_to_lcd(0x0F); // Display, Cursor, blink = 1 send_to_lcd(0x01); // clear Display pause(20000); // länger Zeit warten send_to_lcd(0x06); // Entry-Mode send_to_lcd(0x02); // Cursor @ Home } ////////////// in der Main ///////////////// #include "lcd.h" void main(void) { WDT_off(); uart_init(); lcd_init(); while (1) { } } Auf dem Display passiert aber leider nichts :o( Kein Cursor oder sonstiges ist zu sehen. Wie gesagt, ich weiß dass das Display funktioniert. Ich kann es mit CodeVision ansteuern. Was mach ich den falsch?? Ist die Initialisierung so richtig?? Ich würde mich über eine Antwort wirklich sehr freuen!! Schönen Sonntag noch, Grüße Marcel
vielleicht hilft das weiter: Beitrag "LCD EA DIP204 KS0073 4-Bit, 8-Bit und serielle C-Routinen" (DIP-204 Ansteuerung in C für alle 3 Varianten 4/8/SPI-Mode, jedoch für 8051-Familie, lässt aber leicht portieren)
>send_to_lcd(0x20); // schaltet in den 4 Bit Modus >pause(20000); // länger Zeit warten Die erste 0010 musst Du alleine senden, nicht mit mit 2 Hablbytes. Dazu kannst Du Deine send_to_lcd nicht verwenden. Dann fragst Du auch nirgens das BUSY-Flag ab. Außerdem musst Du beim KS0073 eine Zykluszeit zwischen 2 Sequenzen einhalten, auch zwischen den 2 Nibbles. Tschau Max
@ Max, danke erst mal für deine Antwort. Hmmm, das Busy-Flag!! Da habe ich mal eine Funktion geschrieben: ///////////////// ausschnitt aus dem Programm: (habe jetzt eine .c Datei daraus gemacht!!! #include "uart.h" #include "lcd_test.h" #define LCD PORTC #define LCD_D DDRC #define LCD_PIN PINC #define RS 0 // Bit[0] --> Umschalten zwischen: Befehl(Low) und Daten (High) #define RW 1 // Bit[1] --> Unschalten zwischen: Write (Low) und Read (High) #define EN 2 // Bit[2] --> Enable bei fallender Flanke #define BF 7 // Bit[7] --> Busy Flag am Display busy_flag() { LCD&=~(1<<RS); // RS auf Low LCD|=(1<<RW); // RW auf High toggel_en(); // EN "toggeln" --> high / low while ( !(LCD_PIN & (1<< BF)) ) { uart_putchar('B'); }; LCD&=~(1<<RW); //RW auf Low } das Bit wird aber nie gesetzt!! (endlos-schleife) Was mach ich den schon wieder falsch?? Ich sehe schon, das sieht nach großer Verzweifelung aus. Ab wann kann man das Busy-Flag abfragen? noch vor der Init?? Was meinst du mit: "eine Zykluszeit zwischen 2 Sequenzen"?? In toggel warte ich doch eine ganze weile bis ich wieder weiter schreiben?? Danke für eure Bemühungen!!!!
Ich habe meine Funktion Busy noch mal umgeschrieben: busy_flag() { U8 sperre = 1; LCD&=~(1<<RS); //RS auf Low LCD|=(1<<RW); //RW auf High LCD|=(1<<EN); //EN auf High pause(100); while ( !(sperre ) ) { LCD|=(1<<EN); //EN auf High pause(100); LCD&=~(1<<EN); //EN auf Low pause(100); if(!(LCD_PIN & (1<< BF))) { sperre = 0; } LCD|=(1<<EN); //EN auf High pause(100); LCD&=~(1<<EN); //EN auf Low pause(100); uart_putchar('B'); }; LCD&=~(1<<RW); //RW auf Low } geht aber immer noch nicht!!
Bei HD44780 darf man das BUSY-Flag erst nach der Erstinitialisierung abfragen. Bei KS0073 soweit ich weiß, geht das sofort. 4 Bit Initialisierung ist bei KS0073 eigentlich einfach, nur das erste 0010 muß einzeln gesendet werden. In manchen Fällen kommt es dadurch aber zu Problemen, z.B. wenn Du das Programm durch einen Reset startest, von dem der KS0073 aber nichts mitbekommt. Versuchs auch mal durch aus/einschalten. Andere Frage: Wie hast Du den RESET-PIN gesetzt und hast Du den Kontrast richtig eingestellt?
@ Matthias, danke für deine Antwort!! Also ich habe den Reset-Pin gar nicht belegt, der hängt frei rum !!! Muss man den zwingend belegen?? Der Kontrast ist aber OK. Nach vielen Stunden habe ich es bereits hin bekommen das ich das LCD sauber initialisieren kann. Auch das positionieren des Cursors funktioniert ohne Probleme. Jetzt kommen die nächsten Probleme :o( Ich möchte auf das Dispalay einfach nur ein Zeichen schreiben aber das klappt natürlich nicht!!! (wieso auch......) die Funktionen: void toggel_en() { pause(10000); //busy_flag(); LCD|=(1<<EN); //EN auf High pause(10000); LCD&=~(1<<EN); //EN auf Low pause(10000); } void send_to_lcd(U8 byte) { LCD = (byte&0xf0); // das erste Nibbel an die Pins anlegen toggel_en(); // EN "toggeln" --> high / low LCD = (byte<<4); // das zweite Nibbel an die Pins anlegen toggel_en(); // EN "toggeln" --> high / low } void send_data(U8 byte) { LCD |= (1<<RS); // generell mal RS Pin auf High LCD &= ~ (1<<RW); // generell mal RW Pin auf low send_to_lcd(byte); } void lcd_putchar(U8 signe) { send_data(signe); } Der Funktionsaufruf in main: lcd_putchar(0x41); Ich habe ja einige Programmbeispiele im Netz gefunden aber bei jedem ist es irgendwie gleich. Ich weiß nicht wo der Fehler ist!! Ich habe die Vermutung dass ich irgend etwas vergessen habe einzustellen oder zu initialisieren, nur weiß ich nicht was. Muss man noch irgendwelche Scroll-Funktionen aktivieren??? Wäre über einen hilfreichen Hinweis sehr dankbar!! Grüße, Marcel
>Also ich habe den Reset-Pin gar nicht belegt, der hängt frei rum !!! >Muss man den zwingend belegen?? Nicht zwingend, aber sinnvoll RESET-Pin mit in den System-Restkreis aufzunehmen, ggf. einen Portpin opfern. Überlegung wäre, gleich das Display im SPI/seriellen Mode zu betreiben... >Stunden habe ich es bereits hin bekommen das ich das LCD sauber >initialisieren kann. Auch das positionieren des Cursors funktioniert >ohne Probleme. Schon mal ein Anfang, Steuerzeichen senden dürfte ok sein. Nun scheint das Problem beim Daten senden zu liegen. Auf Anhieb sehe ich keinen Fehler, hast Du mal die Lcd_Init mit anderen Parametern probiert, wie im EA Dip-204 Datenblatt? Wie groß ist pause(10000) in realer Zeit?
@ Matthias, danke für die Antwort!!! Gerade eben habe ich etwas gefunden!! Also ich schreibe in der main: lcd_gotoxy(4,3); // zufällig irgend wo hin springen lcd_putchar(0x41); // Zeichen ausgeben Jetzt ist mein Cursor an die Stelle gesprungen und dann zwei stellen zurück. Am Anfang dachte ich das da irgend etwas mit dem scrollen nicht stimmt und das Display einfach in die falsche Richtung schreibt. ABER!!!! wie es der Zufall will, ist die Adresse 0x41 genau X=2, Y=3. Jetzt denke ich mal das ich mit putchar(0x41) an die stelle springe und nicht dem display sage, er soll den wert anzeigen. Aber wie sage ich ihm das denn?? Hat das etwas mit den SEG-Ram zu tun??? Schönen Abend noch!!!
... ob Daten oder Steuerzeichen übertragen werden wird mit RS festgelegt. RS = 1 Daten RS = 0 Steuerzeichen dann prüfe mal ob RS auch wirklich richtig gesetzt wird...
Mir fehlen tatzächlich die 5V an dem Pin!!! Kann es sein das es daran liegt das die Datenleitung und RS am gleichen Port hängen?? Da gibt es doch Probleme: void send_to_lcd(U8 byte) { LCD = (byte&0xf0); // das erste Nibbel an die Pins anlegen toggel_en(); // EN "toggeln" --> high / low //LCD = (byte<<4); // das zweite Nibbel an die Pins anlegen byte = byte<<4; LCD = (byte&0xf0); toggel_en(); // EN "toggeln" --> high / low } oder sehe ich das falsch?? Wird bei LCD wirklich nur die obersten Bits geändert?? Grüße
Ja genau, das war der Fehler!! Durch den Befehl: byte<<4 werden das untere Nibbel mit 0000 gefüllt und somit steht dann auch an RS = 0!! Danke für die Hilfe!!! Schönen Abend noch und Grüße, Marcel
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.