Hi, ich bin hier am verzweifeln und ich hoffe ihr könnt mir helfen. Ich habe ein Display Typ: HD44780 (2x16 Zeichen) gegen selbigen Typ mit 4x20 Zeichen getauscht. Software nicht angefasst und laut Datenblatt ist das auch nicht nötig. Habe alle Daten (Spannungen, Pinnbelegungen) geprüft, diese stimmen überein. Wie gesagt, so wie ich gelesen habe muss ich an der Software nichts ändern. (wenn ich das zweizeiler wieder anschließe funktioniert wieder alles) Meine Frage nun: Was mache ich falsch, wenn ich folgende Ausgabe auf dem 4-Zeiler bekomme: Zeile 1: XXXXXXXXXXXXXXXXXXXX Zeile 2: Zeile 3: XXXXXXXXXXXXXXXXXXXX Zeile 4: ein "X" repräsentiert ein komplett gefülltes Kästchen. Ich erhalte auch keine "kryptischen Zeichen" etc. Muss ich an der Software doch was ändern? (Ich finde in den Datenblättern eigentlich keine Information dazu, mir gibt jedoch zu bedenken, dass ich das Display in der Initialisierung als "ein" oder "zwei" - zeiler konfigurieren muss. Ein "vierzeiler" existiert im zum Display gehörigen Datenblatt nicht.) Danke
Na sicher must du an der Software was ändern. Woher soll der Controller denn wissen, das er jetzt 4 Zeilen ansteuern kann.
Manfred G. schrieb: > Na sicher must du an der Software was ändern. Woher soll der > Controller > denn wissen, das er jetzt 4 Zeilen ansteuern kann. er weis es noch nicht - aber er sollte doch eigentlich die zwei bisherigen Zeilen beim neuen Display in die oberen beiden Zeilen schreiben
Hi Thomas, im Datenblatt zum Display steht etwas zur Adressierung der 4 Zeilen. Wie von Manfred schon geschrieben, ist die Anzeige korrekt für das 2x 16 Zeichen Display.
Hi >Was mache ich falsch, wenn ich folgende Ausgabe auf dem 4-Zeiler >bekomme: >Zeile 1: XXXXXXXXXXXXXXXXXXXX >Zeile 2: >Zeile 3: XXXXXXXXXXXXXXXXXXXX >Zeile 4: >ein "X" repräsentiert ein komplett gefülltes Kästchen. Das Display ist nicht initialisiert. MfG Spess
1. Der 44780 hat extra ein Bit, mit dem man ihn zwischen zwei und vier Zeilen umschalten kann. Die schwarzen Blöcke kommen wahrscheinlich davon. 2. Die Adressen der Zeilen sind im Displayspeicher nicht fortlaufend angeordnet, sondern versetzt.
Hast du nach der Initialisierung mal "Busy" befragt, ob das Display fertig ist?
Hi >1. Der 44780 hat extra ein Bit, mit dem man ihn zwischen zwei und vier >Zeilen umschalten kann. Die schwarzen Blöcke kommen wahrscheinlich >davon. Stimmt nicht. Der HD44780 kann nur zwischen ein- und zweizeilig umgeschaltet werden. MfG Spess
ich verwende keine rückleitungen zum µc. und kann diese leider nicht nachträglich anbringen. für mich wäre interessant zu wissen, woher ihr diese information habt. ich verwende folgendes db: http://www.crystalfontz.com/controllers/Hitachi_HD44780.pdf (link wurde mir vom händer mitgegeben) ich lese dort auf seite 24/60 unter dem punkt "Initializing by Internal Reset Circuit": "2. Function set: DL = 1; 8-bit interface data N = 0; 1-line display <----- ?????! F = 0; 5 × 8 dot character font"
Seite 26 steht folgendes und bitte beherzigen. DL = 1: 8 bits, DL = 0: 4 bits N = 1: 2 lines, N = 0: 1 line
>>ein "X" repräsentiert ein komplett gefülltes Kästchen. > >Das Display ist nicht initialisiert. Was dann meist an einem falschen Timing für das Display liegt.
holger schrieb: >>>ein "X" repräsentiert ein komplett gefülltes Kästchen. >> >>Das Display ist nicht initialisiert. > > Was dann meist an einem falschen Timing für das > Display liegt. Ja. Möglicherweise kannst du das Display zum Leben erwecken, wenn du die Wartezeiten ein wenig großzügiger gestaltest. Eventuell braucht das 4-zeilige Display nach Anlegen der Betriebsspannung länger zum Hochfahren als das kleinere.
>alles beide wurde erfolglos versucht :(
Zeig doch mal deinen kompletten Code.
Dann gibst du mal an welchen uC du benutzt und mit
welchem Takt der läuft. Pinbelegung des LCD wäre dann
auch hilfreich.
Dann muss hier keiner raten.
Controller ATMEGA32 mit 16Mhz (geprüft, funktioniert!) Code: ---------------
1 | #define F_CPU 16e6
|
2 | |
3 | //INCLUDEs
|
4 | #include <avr/io.h> |
5 | #include <util/delay.h> |
6 | |
7 | void rs (uint8_t wert) |
8 | {
|
9 | if (wert == 1) |
10 | PORTD |= (1<<PD3); //setzen |
11 | else
|
12 | PORTD &= ~(1<<PD3); //löschen |
13 | }
|
14 | |
15 | void e (void) |
16 | {
|
17 | PORTD |= (1<<PD2); //setzen |
18 | _delay_us(100); |
19 | PORTD &= ~(1<<PD2); //löschen |
20 | _delay_us(100); |
21 | }
|
22 | |
23 | void vierBitBefehl (unsigned char Nibble) |
24 | {
|
25 | unsigned char hilf; |
26 | hilf = PORTD & 0b00001111; // Datenbits löschen, Steuerpins übernehmen liegen schon da |
27 | PORTD = (Nibble & 0b11110000) | hilf; //höherwertige Datenpins und Steuerpins |
28 | _delay_us(100); //wieder angehängt |
29 | e(); |
30 | Nibble << 4; |
31 | hilf = PORTD & 0b00001111; // Datenbits löschen, Steuerpins übernehmen liegen schon da |
32 | PORTD = (Nibble & 0b11110000) | hilf; //höherwertige Datenpins und Steuerpins |
33 | _delay_us(100); //wieder angehängt |
34 | e(); |
35 | }
|
36 | |
37 | void lcd_befehl (unsigned char Befehl) |
38 | {
|
39 | rs(0); |
40 | vierBitBefehl (Befehl); |
41 | _delay_ms(1); |
42 | }
|
43 | |
44 | void lcd_zeichen (char Zeichen) |
45 | {
|
46 | rs(1); |
47 | vierBitBefehl (Zeichen); |
48 | _delay_ms(1); |
49 | }
|
50 | |
51 | void lcd_clear (void) |
52 | {
|
53 | lcd_befehl(0x01); //clear Display |
54 | _delay_ms(4); |
55 | lcd_befehl(0x02); //Cursor home |
56 | _delay_ms(4); |
57 | }
|
58 | |
59 | void lcd_text (char Text[]) |
60 | {
|
61 | unsigned int stelle = 0; |
62 | while(Text[stelle] != '\0') // bis zum Textende |
63 | {
|
64 | lcd_zeichen(Text[stelle]); // Textzeichen ausgeben |
65 | stelle++; // nächste Zeichen |
66 | }
|
67 | }
|
68 | |
69 | void zeile (uint8_t z) |
70 | {
|
71 | switch (z) |
72 | {
|
73 | case 1: lcd_befehl (0x80 + 0x00); break; |
74 | case 2: lcd_befehl (0x80 + 0x40); break; |
75 | case 3: lcd_befehl (0x80 + 0x14); break; |
76 | case 4: lcd_befehl (0x80 + 0x54); break; |
77 | }
|
78 | }
|
79 | |
80 | |
81 | void lcd_init (void) |
82 | {
|
83 | _delay_ms(1000); //nach dem Einschalten erst mal warten |
84 | //lcd_befehl (0b00100000); //Interface auf 4Bit
|
85 | lcd_befehl (0b00101000); //2zeilig, 5x8 --> Function Set |
86 | lcd_befehl (0b00001000); //aus --> Display ein/aus |
87 | lcd_befehl (0b00000001); //löschen --> Display löschen |
88 | lcd_befehl (0b00000110); //Kursor n. rechts, kein Display shift --> Entry Mode Set |
89 | lcd_befehl (0b00010100); //--> Cursor/Display Shift |
90 | lcd_befehl (0b00001100); //ein --> Display ein/aus |
91 | lcd_befehl (0b00000010); //--> Kursor zum Anfang |
92 | lcd_zeichen('a'); |
93 | }
|
94 | |
95 | |
96 | int main (void) |
97 | {
|
98 | DDRD = 0xFF; |
99 | PORTD = 0xFF; |
100 | lcd_init(); |
101 | while (1) // Mainloop |
102 | {
|
103 | lcd_text("Hallo"); |
104 | lcd_text("test"); |
105 | }
|
106 | return 0; |
107 | }
|
:
Bearbeitet durch User
sorry, pinnbelegung vergessen: rs = D3 e = D2 B4 = D4 B5 = D5 B6 = D6 B7 = D7
Dann mach mal die Zeiten ein wenig länger. Du kannst ruhig übertreiben. Bei der LCD Ansteuerung hast du es mit Mindestzeiten zu tun. D.h. zum Beispiel der E-Puls muss eine gewisse Mindestlänge haben, die sich im µs Bereich abspielt. Er darf aber ruhig 2 Stunden lang sein. Dein LCD zeigt die Blöcke an. Das ist ein typisches Indiz dafür, dass es nicht initialisiert. Und das ist wiederrum entweder ein Verdrahtungsfehler oder ein Timingproblem (wenn es sich um im Prinzip den gleichen Controller im LCD handelt). Ob das LCD auf 1 oder 2 Zeilig initialisiert wird, ist dafür erst mal unerheblich. Dazu kommt es nämlich gar nicht, denn sonst würde man die beiden Balkenreihen nicht sehen.
HI Vergleiche mal deine lcd_init mit dem Ablaufplan auf S.47 des Datenblatts (Figure 26 4-Bit Interface). MfG Spess
Hä? Das hier
1 | void lcd_init (void) |
2 | {
|
3 | _delay_ms(1000); //nach dem Einschalten erst mal warten |
4 | //lcd_befehl (0b00100000); //Interface auf 4Bit
|
5 | lcd_befehl (0b00101000); //2zeilig, 5x8 --> Function Set |
6 | lcd_befehl (0b00001000); //aus --> Display ein/aus |
7 | lcd_befehl (0b00000001); //löschen --> Display löschen |
8 | lcd_befehl (0b00000110); //Kursor n. rechts, kein Display shift --> Entry Mode Set |
9 | lcd_befehl (0b00010100); //--> Cursor/Display Shift |
10 | lcd_befehl (0b00001100); //ein --> Display ein/aus |
11 | lcd_befehl (0b00000010); //--> Kursor zum Anfang |
12 | lcd_zeichen('a'); |
13 | ...
|
hat auf deinem 2-zeiligen LCD funktioniert? Das glaub ich nicht. Niemals. Da fehlt die Umschaltung in den 4 Bit Modus bzw. die ist 'auskommentiert'. Deswegen in Anführungszeichen, weil selbst dann die Umschaltung nicht korrekt gemacht ist.
:
Bearbeitet durch User
Das hier
1 | void vierBitBefehl (unsigned char Nibble) |
2 | {
|
3 | unsigned char hilf; |
4 | hilf = PORTD & 0b00001111; // Datenbits löschen, Steuerpins übernehmen liegen schon da |
5 | PORTD = (Nibble & 0b11110000) | hilf; //höherwertige Datenpins und Steuerpins |
6 | _delay_us(100); //wieder angehängt |
7 | e(); |
8 | Nibble << 4; |
ist auch Quatsch. Ich behaupte: diese Funktionen haben noch nie richtig funktioniert. Egal ob 2 zeiliges LCD oder nicht.
Deiner lcd_init () fehlt die Resetsequenz aus dem HD44780 Datenblatt. Darum geht das nicht. Versuch mal die HEX Datei aus dem Anhang.
den code habe ich inzw. verändert - da der original ja offensichtlich verändert werden muss. wie hättet ihr den initialisierungsteil gemacht?
holger schrieb: > Deiner lcd_init () fehlt die Resetsequenz aus dem > HD44780 Datenblatt. Darum geht das nicht. > > Versuch mal die HEX Datei aus dem Anhang. also mit der hex klappt es leider auch nicht :( ausgabe unverändert... was meinst du mit resetsequenz fehlt?
>> Versuch mal die HEX Datei aus dem Anhang. > >also mit der hex klappt es leider auch nicht :( >ausgabe unverändert... Komisch. Mein Code funktioniert mit mindestens 20 verschiedenen Displays ohne Probleme. Was hast du mit der RW Leitung gemacht?
rw liegt ohne umwege auf masse... kannst du deinen code posten bitte..? vorallem deine init wäre interessant..
Thomas schrieb: > was meinst du mit resetsequenz fehlt? Steht, wie hier schon geschrieben wurde, im Datenblatt auf Seite 47: Du musst nach dem ersten Warten dreimal einen bestimmten Befehl senden mit entsprechender Wartezeit dazwischen. Erst dann kannst du mit deiner Init-Routine weiter machen. Allerdings solltest du zunächst an der Befehlsübertragung arbeiten, damit auch das am Display ankommt, was ankommen soll.
Was auch sein kann: Die Pinbelegung der Displays ist (leicht) unterschiedlich. Been there, seen it...
Hallo Thomas, es könnt noch was ganz anderes sein. Ich arbeite viel mit diesen Displays und ab und zu geht auch mal eins kaputt. das Fehlerbild ist dann genau so (oder ähnlich) wie du es beschreibst: Zeile 1: XXXXXXXXXXXXXXXXXXXX Zeile 2: Zeile 3: XXXXXXXXXXXXXXXXXXXX Zeile 4: Das mit der Umstellung von 2 auf 4 Stellen kommt ran, wenn Du überhaupt eine Information anzeigen kannst. Dafür ist es erstmal egal ob die Zeile stimmt. Wenn Du sofort nach dem anlegen der Spannung immer nur Balken siehst ist mit Sicherheit das Display kaputt.
hallo, also mit der umstellung 2 auf 4 zeiler, habe ich inzwischen folgende information gefunden: 4 zeiler sind zweizeiler, deren erste und dritte zeile zusammen die erste ausmachen, und zeile 2 und 4 sind die zweite zeile. einen display defekt schließe ich eigentlich aus, ich habe zwei displays versucht --> zweimal das selbe resultat :( kennt jemand eine gute lib, für 4x20 displays? bitte keine lib für 2x19, etc. (expliziet 4x20 gesucht)
Winne Z. schrieb: > Wenn Du sofort nach dem anlegen der Spannung immer nur Balken siehst ist > mit Sicherheit das Display kaputt. Blödsinn! Dieses Bild zeigt jedes nicht initialisierte HD44780-Display. (ich hab durch meine Arbeit an lcd4linux so viele verschiedene HD44780 (und andere) in der Hand gehabt, du kannst mir ruhig glauben)
zur info, es handelt sich um folgendes display: http://www.amazon.de/Character-Display-HD44780-Controller-Blacklight/dp/B00CD2DKQO#productDescription
Thomas schrieb: > kennt jemand eine gute lib, für 4x20 displays? > bitte keine lib für 2x19, etc. (expliziet 4x20 gesucht) Peter Fleurys HD44780 Lib ist so gut, das man so etwas nicht mehr selber machen muss: http://homepage.hispeed.ch/peterfleury/avr-software.html#libs Ist interruptfest, einfach auch auf exotische Pinbelegungen zu konfigurieren und braucht selber auch nix ISR. Ich nehme nur noch die, warum soll man das Rad neu erfinden? Michael Reinelt schrieb: > Dieses Bild zeigt jedes nicht initialisierte HD44780-Display. So isses. Man sollte sich eher Sorgen machen, wenn das Display keinen Balken zeigt. Dann kann man nur noch hoffen, das es die falsche Kontrasteinstellung ist.
:
Bearbeitet durch User
moin - ich hab zwar erst 2 LCD's verbaut und das 2. hatte auch diese Anzeige -> aber wie meisstens: think simple! ... am Kontrast gedreht und alles ist gut lesbar! Auf 2 Zeilen muß er natürlich noch umstellen... bud
Ich hab aber auch in den Datenblättern keinen Hinweis gefunden, wie man ein 4-Zeiliges Display korrekt initialisiert. Ich hab nur das Bit gefunden, mit dem man zwischen 1-zeilig und 2-zeilig umschaltet. Das Bit für 4-zeilig kenn ich nicht. Ich hab jedenfalls den Effekt - so ich mich richtig erinnere - dass das Display erst in Zeile 1, dann in Zeile 3 weiterschreibt, dann in Zeile 2 und dann in Zeile 4 - ohne Positionierungsbefehle natürlich. Das was aber bei der Initialisierung helfen sollte, dass man erstens mit Google genau, präzise das zum Display passende Datenblatt sucht (DEM....), und dann noch ähnliche Datenblätter sucht und schaut, was ähnliche Module machen. Da gibt es kleine aber wichtige Unterschiede. Ich verwende immer www.ribu.at und gehe dort auf die Optoelektronik, der hat gute Links zu den Datenblättern. Es sind leider die Initialisierungssequenzen nicht alle gleich. Was mir auch geholfen hat: Oft ist nur der Kontrast ganz weit daneben. Wenn ich mich richtig erinnere, ist die Spannung am Kontrast Pin eher bei 0 Volt als bei 5Volt für gute Sicht. Mario
Thomas schrieb: > zur info, es handelt sich um folgendes display: > http://www.amazon.de/Character-Display-HD44780-Controller-Blacklight/dp/B00CD2DKQO#productDescription > Um es gleich vor weg zu sagen, ich habe keine Ahnung von C. Habe mich jedoch auch schon mit solchen Sachen herumgeärgert. Leider ist der Datenblattauszug bei Amazon schlecht zu lesen, aber " Die hilfreichsten Kundenrezensionen " machen mich ein wenig stuzig. Wieso redet der von *I²C* ? Fully assembled and tested Serial LCD 20x4 Module Und wieso ist in der Beschreibung von einem seriellem Modul die Rede ? Bernd_Stein
Thomas schrieb: > Was stimmt mit der befehlsuebertragung denn nicht?? Du hast bei dem Bitshift das "=" vergessen und überträgst deshalb zweimal dasselbe Nibble. Das
1 | Nibble << 4 |
ist eine sinnlose Aussage, was soll da passieren? Was du meinst, ist:
1 | Nibble <<= 4 |
Damit schiebst du das untere Nibble ins obere. Eigentlich sollte dir der Compiler das auch als Warnung ausgeben (Unused value).
:
Bearbeitet durch User
Mit dem Nibble hast du recht, danke für den Hinweiß. Ist jedoch leider auch nicht der Fehler, ich hab das eigentlich übergeben und zum zusammenkürzen fürs Forum ist der Fehler passiert. Ausgebessert --> versucht --> immer noch das selbe. Kontrast verdrehe ich jedesmal, da mir der Kontrasteffekt bekannt ist. Peter Fleurys Lib werde ich nacher mal versuchen. Ich muss dazu sagen, ich wollte das Teil selber schreiben, weil mit Peter Fleurys Lib mit der restlichen Software der Speicher überschritten wird.
Hast du die Init-Routine inzwischen repariert?
1 | void lcd_init (void) |
2 | {
|
3 | _delay_ms(1000); //nach dem Einschalten erst mal warten |
4 | |
5 | // Dreimal denselben Befehl mit großzügig Wartezeit dazwischen
|
6 | lcd_befehl (0b00110000); //Initbefehl |
7 | _delay_ms(10); |
8 | lcd_befehl (0b00110000); //Initbefehl |
9 | _delay_ms(10); |
10 | lcd_befehl (0b00110000); //Initbefehl |
11 | _delay_ms(10); |
12 | |
13 | // Hier dann weiter
|
14 | }
|
Ist Euch das entgangen oder wieso reagiert Ihr nicht darauf ? Beitrag "Re: Wechsel vom zwei- zum vierzeiler HD44780" Bernd_Stein
Bernd Stein schrieb: > Ist Euch das entgangen oder wieso reagiert Ihr nicht darauf ? > > Beitrag "Re: Wechsel vom zwei- zum vierzeiler HD44780" > > Bernd_Stein Wenn's so ausschaut wie am Bild ist es weder I2C noch seriell, sondern ganz "normal" parallel anzusteuern.
Thomas schrieb: > Peter Fleurys Lib werde ich nacher mal versuchen. Aber Achtung. Der Fleury Code will eine Verbindung zum R/W Pin des LCD um das Busy Waiting machen zu können. Ist die nicht vorhanden, dann hängt der Code, weil er auf die Rückmeldung vom LCD wartet, die nie kommt.
alles klar ;) - werde mich dran halten danke für den hinweis
bei AM.... steht I2C serieller Anschluß -> d.h. Ansteuerung über TWI des A 32 ... bud
Vlt kann der TO mal aufklären bzgl der Anschlüsse des Moduls.
Ein weiterer Stolperstein könnte sein, dass die Pausen bei der Initialisierung zu kurz sind. Reset- und Cursor-Home-Befehl benötigen laut Datenblatt über 1,5ms zur Ausführung, die Wartezeit beträgt aber nach der fallenden Flanke von e() nur 100µs.
Felix Pflaum schrieb: > Ein weiterer Stolperstein könnte sein, dass die Pausen bei der > Initialisierung zu kurz sind. Reset- und Cursor-Home-Befehl benötigen > laut Datenblatt über 1,5ms zur Ausführung, die Wartezeit beträgt aber > nach der fallenden Flanke von e() nur 100µs. alles schon versucht... inzwischen hab ich ne wartezeit von 4ms nach jedem befehl
Thomas schrieb: > Felix Pflaum schrieb: >> Ein weiterer Stolperstein könnte sein, dass die Pausen bei der >> Initialisierung zu kurz sind. Reset- und Cursor-Home-Befehl benötigen >> laut Datenblatt über 1,5ms zur Ausführung, die Wartezeit beträgt aber >> nach der fallenden Flanke von e() nur 100µs. > > alles schon versucht... inzwischen hab ich ne wartezeit von 4ms nach > jedem befehl Solange du die Balken auf dem LCD hast, sind für dich nur die ersten paar Befehle in der Init interessant. Ob das Clear richtig funktioniert oder nicht, kommt später. Die erste Initialisierung, das Umstellen auf 4 Bit Interface, das ist der Knackpunkt momentan. Wenn das klappt, dann verschwinden auch die Balken und man kann weiter sehen. Aber solange die Balken da sind, ist alles weitere relativ uninteressant. Fokus auf das zur Zeit Wesentliche!
Also nix mit I2C oder seriell. Dann richtig anschließen, Datenblatt studieren und init-Routine richtig implementieren. Tipps dazu gabs ja schon. Unbedingt darauf achten, dass die Pins richtig beschaltet sind. Es gibt zwar einen Quasi-Standard, aber ich hatte auch schon Displays mit anderer Belegung.
Denb Anfang von Felix Pflaumes Init kannst du übrigens nicht nehmen. Zum Umschalten auf den 4 Bit Modus kannst du die Funktion lcd_befehl noch nicht benutzen. AVR-GCC-Tutorial Such nach LCD. Da gibt es einen weiterführenden Link mit Routinen.
kompilierungsfeher mit der lib von Peter Fleury: In function `main': prog.c:(.text+0x32): undefined reference to `lcd_init' prog.c:(.text+0x3e): undefined reference to `lcd_clrscr' prog.c:(.text+0x46): undefined reference to `lcd_puts' prog.c:(.text+0x4e): undefined reference to `lcd_puts' prog.c:(.text+0x56): undefined reference to `lcd_gotoxy' prog.c:(.text+0x5c): undefined reference to `lcd_putc' prog.c:(.text+0x66): undefined reference to `lcd_command' prog.c:(.text+0x6e): undefined reference to `lcd_puts' prog.c:(.text+0x76): undefined reference to `lcd_clrscr' prog.c:(.text+0x7e): undefined reference to `lcd_puts_p' prog.c:(.text+0x86): undefined reference to `lcd_puts_p' prog.c:(.text+0x8c): undefined reference to `lcd_command' prog.c:(.text+0x96): undefined reference to `lcd_command' prog.c:(.text+0x9a): undefined reference to `lcd_clrscr' prog.c:(.text+0xae): undefined reference to `lcd_puts' prog.c:(.text+0xb6): undefined reference to `lcd_clrscr' prog.c:(.text+0xbe): undefined reference to `lcd_puts' prog.c:(.text+0xc4): undefined reference to `lcd_command' prog.c:(.text+0xd0): undefined reference to `lcd_data' prog.c:(.text+0xe4): undefined reference to `lcd_gotoxy' prog.c:(.text+0xea): undefined reference to `lcd_putc' prog.c:(.text+0xf0): undefined reference to `lcd_putc' und das am beispielprogramm??
Das ist natürlich wahr, Karl-Heinz, ich habe übersehen, dass die Funktion "lcd_befehl" erst nach der erfolgreichen Umschaltung auf den 4-bit-Modus funktionieren kann. Das kann der Grund dafür sein, dass die Balken nicht verschwinden. Die drei ersten Befehle und den Umschaltbefehl müsste man dann etwa so umsetzen:
1 | _delay_ms(1000); |
2 | PORTD &= 0x0F; |
3 | rs(0); |
4 | PORTD |= 0x30; // DB5 und DB4 auf 1 |
5 | _delay_ms(50); // Übertrieben lange warten |
6 | e(); // Befehl 3x ausführen |
7 | _delay_ms(50); |
8 | e(); |
9 | _delay_ms(50); |
10 | e(); |
11 | _delay_ms(50); |
12 | |
13 | PORTD &= 0x0F; // Auf 4-bit-Modus |
14 | PORTD |= 0x20; // schalten |
15 | _delay_ms(1); |
16 | e(); |
:
Bearbeitet durch User
Thomas schrieb: > kompilierungsfeher mit der lib von Peter Fleury: > > ( jede menge 'undefined References' ) > > und das am beispielprogramm?? Wie wäre es, wenn du das C-File mit dem Source Code der Routinen auch mit ins Projekt aufnimmst (lcd.c)?
:
Bearbeitet durch User
ein erstes lebenszeichen: nun flackert das display kurz auf und statt jeder zweiten zeile sehe ich nun die erste und dritte wie gehabt, und in zeile 2 und 4 die hälte von oben nach unten je zeichen. aktueller code:
1 | #define F_CPU 16e6
|
2 | |
3 | //INCLUDEs
|
4 | #include <avr/io.h> |
5 | #include <util/delay.h> |
6 | |
7 | void rs (uint8_t wert) |
8 | {
|
9 | if (wert == 1) |
10 | PORTD |= (1<<PD3); //setzen |
11 | else
|
12 | PORTD &= ~(1<<PD3); //löschen |
13 | }
|
14 | |
15 | void e (void) |
16 | {
|
17 | PORTD |= (1<<PD2); //setzen |
18 | _delay_ms(100); |
19 | PORTD &= ~(1<<PD2); //löschen |
20 | _delay_ms(100); |
21 | }
|
22 | |
23 | void vierBitBefehl (unsigned char Nibble) |
24 | {
|
25 | unsigned char hilf; |
26 | hilf = PORTD & 0b00001111; |
27 | PORTD = (Nibble & 0b11110000) | hilf; |
28 | _delay_us(100); |
29 | e(); |
30 | Nibble = Nibble << 4; |
31 | hilf = PORTD & 0b00001111; |
32 | PORTD = (Nibble & 0b11110000) | hilf; |
33 | _delay_us(100); |
34 | e(); |
35 | }
|
36 | |
37 | void lcd_befehl (unsigned char Befehl) |
38 | {
|
39 | rs(0); |
40 | vierBitBefehl (Befehl); |
41 | _delay_ms(1); |
42 | }
|
43 | |
44 | void lcd_zeichen (char Zeichen) |
45 | {
|
46 | rs(1); |
47 | vierBitBefehl (Zeichen); |
48 | _delay_ms(1); |
49 | }
|
50 | |
51 | void lcd_clear (void) |
52 | {
|
53 | lcd_befehl(0x01); //clear Display |
54 | _delay_ms(5); |
55 | lcd_befehl(0x02); //Cursor home |
56 | _delay_ms(5); |
57 | }
|
58 | |
59 | void lcd_text (char Text[]) |
60 | {
|
61 | unsigned int stelle = 0; |
62 | while(Text[stelle] != '\0') // bis zum Textende |
63 | {
|
64 | lcd_zeichen(Text[stelle]); // Textzeichen ausgeben |
65 | stelle++; // nächste Zeichen |
66 | }
|
67 | }
|
68 | |
69 | void zeile (uint8_t z) |
70 | {
|
71 | switch (z) |
72 | {
|
73 | case 1: lcd_befehl (0x80 + 0x00); break; |
74 | case 2: lcd_befehl (0x80 + 0x40); break; |
75 | case 3: lcd_befehl (0x80 + 0x14); break; |
76 | case 4: lcd_befehl (0x80 + 0x54); break; |
77 | }
|
78 | }
|
79 | |
80 | |
81 | void lcd_init (void) |
82 | {
|
83 | _delay_ms(1000); //nach dem Einschalten erst mal sehr lange warten |
84 | rs(0); |
85 | lcd_befehl (0x30); //4 Leitungen |
86 | _delay_ms(5); |
87 | lcd_befehl (0x30); |
88 | _delay_ms(5); |
89 | lcd_befehl (0x30); |
90 | _delay_ms(5); |
91 | lcd_befehl (0x20); //Anzeige 4bit Modus |
92 | lcd_befehl(0x28); //Anzahl zwei Zeilen |
93 | lcd_befehl(0x0C); //Anzeige an, Cursor aus |
94 | lcd_clear(); //Display leeren |
95 | lcd_befehl(0x06); //Schiebemodus |
96 | }
|
97 | |
98 | |
99 | int main (void) |
100 | {
|
101 | DDRD = 0xFF; |
102 | PORTD = 0xFF; |
103 | lcd_init(); |
104 | while (1) // Hauptschleife |
105 | {
|
106 | lcd_text("abcdefghi"); |
107 | lcd_text("jklmnopqr"); |
108 | }
|
109 | return 0; |
110 | }
|
:
Bearbeitet durch User
Bist du sicher, dass es da keine Wackelkontakte gibt? Jumperkabel, schlechtes Breadboard...
Harald Nagy schrieb: > Bist du sicher, dass es da keine Wackelkontakte gibt? Jumperkabel, > schlechtes Breadboard... alles schon doppelt und dreifsch getauscht. ich bin mir sicher. Lötpunkte wurden von mir auch nochmal erneuert.
Thomas schrieb: > nun flackert das display kurz auf und statt jeder zweiten zeile sehe ich > nun die erste und dritte wie gehabt, und in zeile 2 und 4 die hälte von > oben nach unten je zeichen. Ähh wie? (kannst du das aufmalen?)
Thomas schrieb: > aktueller code: >
1 | > void lcd_init (void) |
2 | > { |
3 | > _delay_ms(1000); //nach dem Einschalten erst mal sehr lange |
4 | > warten |
5 | > rs(0); |
6 | > lcd_befehl (0x30); //4 Leitungen |
7 | > _delay_ms(5); |
8 | > lcd_befehl (0x30); |
9 | > _delay_ms(5); |
10 | > lcd_befehl (0x30); |
11 | > _delay_ms(5); |
12 | > lcd_befehl (0x20); //Anzeige 4bit Modus |
13 | >
|
noch nicht ganz richtig. Zur Umschaltung in den 4-Bit Modus kannst du lcd_befehl noch nicht benutzen. lcd_befehl kann erst dann verwendet werden, wenn das LCD schon im 4-Bit Modus ist. Nicht vorher. Warum studierst du denn nicht endlich mal die Routinen in AVR-GCC-Tutorial/LCD-Ansteuerung da kann man das alles nämlich sehen, wenn man den Code mal aufmerksam studiert. Und man kann dort auch sehen, wie man die Sache mit den Konstanten lösen kann, so dass man nicht dauernd mit Hex-Zahlen um sich werfen muss. Das würde der Übersichtlichkeit sehr zuträglich sein, wenn man nicht mit Datenblatt und viel Geduld umständlich eruieren müsste, was du eigentlich bei der Hex-Zahlen Orgie
1 | lcd_befehl(0x28); //Anzahl zwei Zeilen |
2 | lcd_befehl(0x0C); //Anzeige an, Cursor aus |
3 | lcd_clear(); //Display leeren |
4 | lcd_befehl(0x06); //Schiebemodus |
WIRKLICH eingestellt hast. Vielleicht stimmen deine Kommentare. Vielleicht aber auch nicht. Kommentare sind Schall und Rauch. Die Erfahrenen ignorieren sie bei der Fehlersuche sowieso meistens. Du hast irgendwann mal geschrieben, dass du die Dinge lernen willst. Gut. Dazu gehört auch, das man sich ansieht, wie andere gleichartige Problemstellungen lösen. Das ist keine Schande, anderer Leute Code zu studieren. Ganz im Gegenteil, kann man so eine Menge lernen.
:
Bearbeitet durch User
Michael Reinelt schrieb: > Thomas schrieb: >> nun flackert das display kurz auf und statt jeder zweiten zeile sehe ich >> nun die erste und dritte wie gehabt, und in zeile 2 und 4 die hälte von >> oben nach unten je zeichen. > > Ähh wie? (kannst du das aufmalen?) Ja bitte. Die Beschreibung des Teils mit der Hälfte klingt sehr abenteuerlich.
Z1: XXXXXX.. Z2: """""".. Z3: XXXXXX.. Z4: """""".. X = komplett gefüllt " = nur oberer Teil gefüllt
Du hast das Display auch schon gegen einen gleichen Typ getauscht ?
Thomas schrieb: > Z1: XXXXXX.. > Z2: """""".. > Z3: XXXXXX.. > Z4: """""".. > > X = komplett gefüllt > " = nur oberer Teil gefüllt 'Nur oberer Teil gefüllt'. Muss man sich das so vorstellen, dass im 5*8 Pixelblock nur die oberen Pixelzeilen was anzeigen und die unteren nicht? Du also von einem 'A' nur die obere Hälfte siehst? Denn das kannst du nicht verstellen. In dem Fall hat dein LCD einen Hau weg. Da gibt es irgendwo ein Kontaktproblem vom LCD-Glas zur Platine.
Karl Heinz schrieb: > 'Nur oberer Teil gefüllt'. Muss man sich das so vorstellen, dass im 5*8 > Pixelblock nur die oberen Pixelzeilen was anzeigen und die unteren > nicht? Du also von einem 'A' nur die obere Hälfte siehst? Vielleicht kann man das auf einem Foto besser sehen als auf einer Zeichnung.
hat sich erübrigt, denn der "alte Fehler" ist wieder da - hab ewig versucht den zustand wiederherzustellen, jedoch bleibt nun alles wie eh und je.
Karl Heinz schrieb: > Denn das kannst du nicht verstellen. In dem Fall hat dein LCD einen Hau > weg. Da gibt es irgendwo ein Kontaktproblem vom LCD-Glas zur Platine. Falsch. Man kann einen 5x10 Font einstellen. Dies bedeutet allerdings, dass er das Display noch im Einzeilenbetrieb betreibt und sein 2x16 Display auch nicht gelaufen haben kann. Ich tippe hier auf eine Verarsche ... Gruß Jobst
Thomas schrieb: > und das am beispielprogramm?? Es gibt Leute, die setzten ein ganz minimales Grundwissen für die Werkzeugbenutzung voraus. Bei C-Compilern offenbaren sich grobe Fehler in Tiraden von Fehlermeldungen, beim Lötkolben in verbrannten Fingern.
@Thomas Anbei ein Hexfile das funktionieren sollte. Voraussetzung: PortD wird verwendet und R/W ist auf Pin PD1 angeschlossen. Grund: Es wird das sog. Bussyflag abgefragt und selbst definierte Zeichen übertragen.
Danke für das Hex-File - jedoch benötige ich es nicht mehr - habe die Displays zurückgeschickt und mir neue geholt. Diese funktionierten auf Anhieb!! Ich vermute einen serienfehler! "Ich tippe hier auf eine Verarsche ..." traurig solche Antworten zu lesen wenn man ernsthaft Hilfe sucht! Nochmal: Ich habe den Code im Original etwas anderst - und ihn gekürzt und minimal verändert, dass er fürs Forum nicht zu umfangreich wird,...
Mehrmals wurdest Du auf ein defektes Display hingewiesen. Darauf gab es keine Reaktion von Dir. Was erwartest Du da ?
Thomas schrieb: > Danke für das Hex-File - jedoch benötige ich es nicht mehr - habe die > Displays zurückgeschickt und mir neue geholt. Diese funktionierten auf > Anhieb!! > Ich vermute einen serienfehler! > Danke, das Du uns nicht ganz im Ungewissen gelassen hast. Der " Serienfehler " schien schon in der Diskrepanz zwischen schlecht lesbarem - aber dennoch eindeutig als HD44780 standard erkennbar - und der Kundenrezension bei Amazon zu dem Produkt erkennbar zu sein. Beitrag "Re: Wechsel vom zwei- zum vierzeiler HD44780" Bernd_Stein
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.