Hi ihr Checker, ich versuche seit geraumer Zeit ein DOGM081 zum laufen zu bringen, leider ohne Erfolg. Es wird nichts auf dem Display ausgegeben, die restliche Software läuft. Die Hardware ist laut Datenblatt aufgebaut (Schaltplan und Datenblatt sind angehängt). Die Ansteuerungsroutine habe ich von Beitrag "EA DOG-M 3,3V 4-Bit" und sie auf 5V und 1-Zeilen-Display angepasst. Trotzdem geht es nicht :-( Kann mir jemand helfen? // *** Includes ************************************************************* #include "defines.h" #include "global.h" #include <avr/io.h> // Aliases for IO ports etc. #include <util/delay.h> // ************************************************************************ ** #define FUNCTION_SET_EXT 0x21 // 4bit mode, 1 line, instruction table [0,1] #define BIOS_SET 0x1C // 1/5 bios #define POWER_ICON 0x51 // Booster on, contrast C4 on #define FOLLOWER_CONTROL 0x6A // Follower on, Rab0 #define CONTRAST_MODE 0x74 // Contrast C2, contrast C0 #define FUNCTION_SET_BAS 0x30 #define DISPLAY_ON 0x0F // Display on, no curser, no blink #define CLEAR_DISPLAY 0x01 // Clear display, set position 0,0 #define ENTRY_MODE_SET 0x06 // Curserdirection right // *** Routines ************************************************************* void InitDisplay (void) { DISPLAY_RW_OFF; DISPLAY_E_OFF; DISPLAY_RS_OFF; _delay_ms(100); DisplayPutData(0x30); _delay_ms(2); DisplayPutData(0x30); DisplayClock (); DisplayPutData(0x30); DisplayClock (); DisplayPutData(0x20); DisplayClock (); DisplayWriteData(COMMAND, FUNCTION_SET_EXT); DisplayClock (); DisplayWriteData(COMMAND, BIOS_SET); DisplayClock (); DisplayWriteData(COMMAND, POWER_ICON); DisplayClock (); DisplayWriteData(COMMAND, FOLLOWER_CONTROL); DisplayClock (); DisplayWriteData(COMMAND, CONTRAST_MODE); DisplayClock (); DisplayWriteData(COMMAND, FUNCTION_SET_BAS); DisplayClock (); DisplayWriteData(COMMAND, ENTRY_MODE_SET); DisplayClock (); DisplayWriteData(COMMAND, DISPLAY_ON); DisplayClock (); DisplayWriteData(COMMAND, CLEAR_DISPLAY); DisplayClock (); } void DisplayClock (void) { _delay_us (30); // 30µs warten DISPLAY_E_ON; // Clock-Bit auf high _delay_us (0.4); // High muss min. 200ns anliegen DISPLAY_E_OFF; // und jetzt auf low } void DisplayWriteChar (char c) { DisplayWriteData(MESSAGE, c); } void DisplayWriteString (char * str) { while(*str != '\0') { DisplayWriteChar (*str++); } } void DisplayWriteData (U_INT8 rs, U_INT8 data) { if(rs == COMMAND) DISPLAY_RS_OFF; else DISPLAY_RS_ON; DisplayPutData (data); DisplayPutData (data << 4); } void DisplayPutData (U_INT8 data) { //D7 if (data & READ_BIT_7) DISPLAY_D7_ON; else DISPLAY_D7_OFF; //D6 if(data & READ_BIT_6) DISPLAY_D6_ON; else DISPLAY_D6_OFF; //D5 if(data & READ_BIT_5) DISPLAY_D5_ON; else DISPLAY_D5_OFF; //D4 if(data & READ_BIT_4) DISPLAY_D4_ON; else DISPLAY_D4_OFF; //E Puls DISPLAY_E_ON; _delay_us(0.4); DISPLAY_E_OFF; } int main(void) { Init (); // Port und Displayinitialisierung DisplayWriteString("text1"); while(1) {} return 0; }
Hallo, hast du wirklich 10k Widerstände in den Datenleitungen zum Display? Gruß
Ich betreibe das Display mit 5V. Die 10k Widerstände wurden mir empfohlen um die Eingänge zum Display zu schützen. Bei dem, der mir das Empfohlen hat funktioniert die zweizeilige Variante dieses Displays mit Widerständen ohen Probleme, daher denke ich nicht, dass die ausschlaggebend sind.
Hat schon jemand Erfahrungen mit diesen Displays und könnte eventluell meine Initialiserung ansehen? Das wäre echt super!
Und Register Select (RS) und Enable (E) ist nicht angeschlossen? R/W am Display auch nicht? Gruß Jobst
@ Jobst: Doch, rs ist schon angeschlossen. (Controller PC5, Display Port39). In dem kleinen Bild oben siehts aber fast so aus als wenn "RS" mit GND verbunden wäre. Verbindungen der einzelnen Pins habe ich mit dem Multimeter schon durchgemessen.
Hallo, jaja - den Fehler hab ich auch schon gemacht beim zurückschalten auf IS0 - bei dir "FUNCTION_SET_BAS" muss 0x20 gesendet werden, denn 0x30 schaltet wieder auf 8-Bit-Datenbus um Sascha
Hi Sascha, habe FUNCTION_SET_BAS aus 0x20 gestellt, leider funktioniert es immer noch nicht. Kannst Du Dir den Rest vielleicht auch noch anschaun, was ich falsch gemacht habe? Grüße
ok
1 | _delay_ms(100); |
2 | DisplayPutData(0x30); |
3 | _delay_ms(2); <<erhöhen auf 9ms |
4 | DisplayPutData(0x30); |
5 | <<Delay 2.5ms |
6 | DisplayClock (); <<raus |
7 | DisplayPutData(0x30); |
8 | <<Delay 2.5ms |
9 | DisplayClock (); <<raus |
10 | DisplayPutData(0x20); |
mit dem Timing läufts bei mir problemlos, wobei ich noch keinen Test zur minimierung der Delays gestartet habe. was sollen die ganzen DisplayClock() ???? den Clock hast du doch schon in PutData() drin, und das wird ja auch von DisplayWriteData() verwendet! Sascha
Die delays habe ich wie Du gesagt hast angepasst, die Funktion DisplayClock war eine verzweiflungstat gestern, die ich übersehen habe wieder zu entfernen, was ich jetzt gemacht habe. leider geht immer noch nichts. Hier nochmal der abgeänderte Teil der Software: #define FUNCTION_SET_EXT 0x21 // 4bit mode, 1 line, instruction table [0,1] #define BIOS_SET 0x1C // 1/5 bios #define POWER_ICON 0x51 // Booster on, contrast C4 on #define FOLLOWER_CONTROL 0x6A // Follower on, Rab0 #define CONTRAST_MODE 0x74 // Contrast C2, contrast C0 #define FUNCTION_SET_BAS 0x20 #define DISPLAY_ON 0x0F // Display on, no curser, no blink #define CLEAR_DISPLAY 0x01 // Clear display, set position 0,0 #define ENTRY_MODE_SET 0x06 // Curserdirection right void InitDisplay (void) { DISPLAY_RW_OFF; DISPLAY_E_OFF; DISPLAY_RS_OFF; _delay_ms (100); DisplayPutData (0x30); _delay_ms (9); DisplayPutData (0x30); _delay_ms (2.5); DisplayPutData (0x30); _delay_ms (2.5); DisplayPutData (0x20); _delay_us (60); DisplayWriteData (COMMAND, FUNCTION_SET_EXT); _delay_us (60); DisplayWriteData (COMMAND, BIOS_SET); _delay_us (60); DisplayWriteData (COMMAND, POWER_ICON); _delay_us (60); DisplayWriteData (COMMAND, FOLLOWER_CONTROL); _delay_us (60); DisplayWriteData (COMMAND, CONTRAST_MODE); _delay_us (60); DisplayWriteData (COMMAND, FUNCTION_SET_BAS); _delay_us (60); DisplayWriteData (COMMAND, ENTRY_MODE_SET); _delay_us (60); DisplayWriteData (COMMAND, DISPLAY_ON); _delay_us (60); DisplayWriteData (COMMAND, CLEAR_DISPLAY); _delay_us (60); }
Tatsächlich, 10k in den Datenleitungen, was für eine blöde Idee. Erstmal die 10k raus. Man kann da Widerstände reinmachen, aber nicht mehr als 100 bis 330ohm. Mit 10k können die Signale schon so verrundet werden - je nach Eingangs- und Kabelkapazität - dass da keine sinnvollen Daten mehr ankommen. Und dass es zufällig bei jemand anderen funktioniert, muss nichts heissen.
Habe die Widerstände erst gegen 100 Ohm getauscht und dann ganz raus genommen. Leider hat beides nicht geholfen. Hat jemand noch eine Idee?
da du den Displayzustand nicht abfragen kannst, sollten die Delay's ausreichend lang sein - ClearDisplay braucht z.B. 1.08ms lt. Datenblatt. Nach dem erfolgreichen Init sollte ja wenigstens der Cursor zu sehen sein! Ansonsten fällt mir langsam nix mehr ein - häng mal den gesamten Code hier an - nicht das dort noch was im argen liegt. Sascha
Danke für die Hilfe! Das Programm ist aufgeteilt in mehrere Files: - defines.h - global.h - display.c - display_modul.c - init.c Alles, was das Display nicht direkt betrifft habe ich rausgeschmissen, angezeigt wird aber auch so nichts. Die Files habe ich angehängt, da es sonst ein wenig lang werden würde.
mal auf die Schnelle ... da gibts in init.c die Zeile
1 | DDRC &=~ (1 << DDC0); |
die eine Datenleitung wieder auf Eingang schaltet, obwohl weiter oben schon mal alles richtig auf Ausgang war. Sascha
Mein - funktionierendes - Timing für ein DOGM 162
1 | init_display:
|
2 | ldi DATA, 0b00110000 ;Function Set init |
3 | rcall display_nibble |
4 | call delay2ms ;Setup-Zeit für Clear |
5 | |
6 | ldi DATA, 0b00110000 ;Function Set init |
7 | rcall display_nibble |
8 | ldi DATA, 0b00110000 ;Function Set 4bit, 2 Zeilen |
9 | rcall display_nibble |
10 | ldi DATA, 0b00101001 ;Function Set 4bit, 2 Zeilen |
11 | rcall display_nibble |
12 | |
13 | ldi DATA, 0b00101001 ;Function Set 4bit, 2 Zeilen |
14 | rcall display_set |
15 | |
16 | ldi DATA, 0b00010100 ;Bias Set |
17 | rcall display_set |
18 | ldi DATA, 0b01101001 ;Follower Ctrl |
19 | rcall display_set |
20 | ldi DATA, 0b01010011 ;Power Ctrl |
21 | rcall display_set |
22 | ldi DATA, 0b01110000 ;Contrast Set |
23 | rcall display_set |
24 | ldi DATA, 0b00001101 ;Display ein, Cursor aus, Blink ein |
25 | rcall display_set |
26 | ldi DATA, 0b00000001 ;Clear Display |
27 | rcall display_set |
28 | call delay2ms ;Setup-Zeit für Clear |
29 | ldi DATA, 0b00000110 ;EntryMode Cursor inc, Shift aus |
30 | rcall display_set |
31 | call delay2ms ;Setup-Zeit für Clear |
Wichtig ist, dass bei 4bit-Mode am Anfang beim Function Set nur das obere Nibble gesendet wird, das untere weggelassen. Erst wenn der 4bit-Mode eingestellt ist, werden beide Nibbles gesendet.
Ach und nochwas: Man kann die DOGM offenbar durch falsche Ansteuerung blockieren. Also wenn beim Programmieren das Display falsche Daten bekommt, und Du dann den µC neu programmierst, muss auch das Display ein Reset / Spannung kurz weg bekommen, um die neuen Daten zu akzeptieren. Ist nicht immer so, aber mitunter kann es vorkommen. Also immer nach Neuprogrammierung Spannung kurz weg, solange Du noch an den Displayroutinen arbeitest.
Das darf doch nicht wahr sein, wie oft ich die Initialisierungen angesehen habe, mit dem Schaltplan verglichen habe, ... Vielen Dank für die Hilfe und sorry, dass es so ein dummer! Fehler wahr. Grüße, Florian P.S.: Den A...Tritt habe ich mir schon verpasst ;-)
ja, und dann immer - ich poste mal den Codeabschnitt an dem's eigentlich nur liegen kann! Geht's denn nun? Sascha
Ja es funktioniert, ich werde mal alles schön zusammenfassen und dann die 4-Bit-Ansteuerung posten. Man muss nur ein Auge für das Wesentliche haben ;-)
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.