Hallo liebe Leute,
für ein kleines Projekt möchte ich etwas auf einem LCD Display ausgeben.
Dafür habe ich noch eines in meiner Bastelkiste gefunden. 2-Zeilig
angesteuert über einen HD44780 der an einem FC-113 TWI Modul
angeschlossen ist. Eigentlich schön Port Sparend aber das ganze raubt
mir den letzten Nerv.
Das Display initialisiert einfach nicht. Ich habe jetzt schon
verschiedenste Dinge durchprobiert was das verändern der Delays angeht.
Funktioniert hat das ganze schon einmal in der selben Konfiguration,
leider ist das mittlerweile ein wenig her und ich kann meinen Quellcode
nicht mehr finden.
Als Controller benutze ich einen Atmega 32 mit 16MHz.
Das Display habe ich an einem Arduino mit der LCD Bibliothek getestet,
dort zickt es nicht. Ich vermute den Fehler also irgendwo in meiner
initialisierung.
Da ich den Lerneffekt durchs selber machen sehr schätze, möchte ich mich
aber nicht auf eine vorgefertigte Bib verlassen.
Wäre super wenn einmal jemand der häufiger mit LCDs hantiert drüber
schauen könnte.
PS: Der Code wird selbstverständlich noch optimiert wenn es läuft :D
Code:
1
voidlcd_init()
2
{
3
_delay_ms(15);//- Wait for more than 15ms after VDD rises to 4.5V
4
twi_start(SLA_W);
5
twi_send_data(lcd_set_8_bit);
6
twi_stop();
7
_delay_ms(5);//- Wait for more than 4.1ms
8
9
twi_start(SLA_W);
10
twi_send_data(lcd_set_8_bit);
11
twi_stop();
12
_delay_us(100);//- Wait for more than 100us
13
14
twi_start(SLA_W);//
15
twi_send_data(lcd_set_8_bit);//interface auf 8 Bit
16
twi_stop();//
17
18
twi_start(SLA_W);//
19
twi_send_data(lcd_set_8_bit);//Interface auf 4 Bit
20
twi_stop();//
21
22
//- From now on in 4-bit-Mode
23
twi_start(SLA_W);//
24
twi_send_data(0x00|(1<<LCD_D5)|(1<<LCD_E)|(1<<LCD_LIGHT));//2 zeilig matrix auf 5x8
Malhiergeschaut schrieb:> twi_start(SLA_W); //> twi_send_data(lcd_set_8_bit); //Interface auf 4 Bit> twi_stop(); //
Schon mal danke für die schnelle Antworten. Das war natürlich ein
ziemlich grober Schnitzer :D
Ist mir tatsächlich die ganze zeit über nicht aufgefallen. Leider läuft
das ganze noch immer nicht. mal gucken ob mir noch mehr solcher Pannen
unterlaufen sind die mir jetzt auffallen. Nach einer Zeit sieht man ja
den Wald vor lauter Code nicht mehr.
hinz schrieb:> Stefan B. schrieb:>> FC-113 TWI Modul>> Schaltplan angesehen?> Datenblatt des PCF8574 gelesen?
Ja im Vorfeld natürlich schon.
Einfaches ein und ausschalten der Hintergrundbeleuchtung die an PIN 3
anliegt funktioniert auch. Werde aber nochmal schauen ob ich nichts
durcheinander gewürfelt habe. Allerdings stimmen meine Zuweisungen in
soweit mit denen von fertigen Bibliotheken überein. Am Arduino
funktioniert das ganze ja auch mit einer fertigen Bib. Naja ein grober
Fehler ist mir ja schon unterlaufen. Ich werde nochmal drüber sehen.
hinz schrieb:> Dir ist klar, dass ein einzelner Schreibzyklus an das eigentliche die> Übertragung von 3 Bytes via I2C erfordert?
3 Bytes?
Kannst du das vielleicht näher erläutern?
Ich habe RS, RW, E, D0-D7 und die Beleuchtung. Das macht 12 Pins.
Nutze ich den 4 Bit-Modus benötige ich von den 8 Datenpins nur 4 , was
mich auf insgesamt 8 zu berücksichtigende Pins bringt. Soweit ich weiß
kann ich per TWI genau ein Byte übertragen. RS, RW, E und Beleuchtung
werden immer mit übertragen und dann jeweils die obere bzw. untere
Hälfte des Datenbytes. Also einmal D7-D4 und einmal D3-D0. Somit komme
ich auf 2 Übertragungen. Ist da ein Denkfehler drin?
Schon traurig wie unfreundlich hier einem Hilfesuchenden geantwortet
wird. Wenn solche Fragen unter eurer Würde sind dann kommentiert sie
lieber gar nicht. Diese passive Aggressivität die hier mitschwingt ist
wirlkich ein Armutszeugnis.
Gleichzeitig TWI zu nutzen und die Eigenarten eines LCD Treibers zu
beachten ist zwar kein Hexenwerk aber wenn man es nicht häufig benutzt
kann man da schonmal etwas übersehen. Man bedenke die Menge an
Informationen die dafür durchforstet werden muss.
Du brauchst einen Puls am Enable Pin um die Daten zu übernehmen. Darum
geht es hier grob gesagt und darin liegt auch dein Denkfehler. Das selbe
Problem hatte ich damals auch als ich mich das erste mal daran gewagt
habe. Vielleicht hilft es dir, zu überlegen, dass du zum einen die Daten
halten musst und zum anderen die Daten „Erlauben“ musst indem du einen
Puls erzeugst.
Hinz wäre es ihm klar gewesen, hätte er wohl kaum hier um Rat gefragt...
Vielen Dank Leute ich weiß bescheid.
Da war also mein Denkfehler. Ich glaube das Selbe ist mir damals schon
passiert, da bin ich aber noch selber darauf gestoßen :D
So kann es gehen.
Danke nochmal für die schnellen Antworten.
Elektro PartY schrieb:> Hinz wäre es ihm klar gewesen, hätte er wohl kaum hier um Rat gefragt...
Lies sein Posting, er wollte keine fix und fertige Erklärung, sondern
einen Hinweis, des Lerneffekts wegen.
Und genau deswegen finde ich Formulierungen wie: Hast du die
Datenblätter gelesen... und Dir ist klar, dass... oder eine 3 Zeilige
Antwort zum („näher erläutern“) völlig deplatziert. Sowas lese ich
andauernd hier im Forum. Absolut passiv aggressiv und unfreundlich.
Aber naja...
Hi,
> hinz schrieb:> Dir ist klar, dass ein einzelner Schreibzyklus an das eigentliche die> Übertragung von 3 Bytes via I2C erfordert?
Das ist so nicht ganz richtig. Du brauchst keinen einzelnen Impuls
sondern eine fallende Flanke an E.
Du kannst also: 1 weglassen und sofort mit 2 beginnen.
Nach Einhaltung der Settingtime E einfach auf 0 und gut ist.
1) Adresse und Daten setzen, E=0
2) Adresse und Daten setzen, E=1
Päuschen
3) Adresse und Daten halten, E=0
Viel Erfolg, Uwe
Uwe schrieb:> Das ist so nicht ganz richtig. Du brauchst keinen einzelnen Impuls> sondern eine fallende Flanke an E.>> Du kannst also: 1 weglassen und sofort mit 2 beginnen.
Nein, siehe Datenblatt des HD44780.
hinz schrieb:> Uwe schrieb:> Das ist so nicht ganz richtig. Du brauchst keinen einzelnen Impuls> sondern eine fallende Flanke an E.> Du kannst also: 1 weglassen und sofort mit 2 beginnen.>> Nein, siehe Datenblatt des HD44780.
Ich arbeite zwar nie mit dem HD44780 aber UWE hat meiner Meinung nach
recht. Nur, handelt es sich bei seiner Variante ja eben auch um einen
Puls. Enable liegt doch in der Regel auf 0.
Setzt du nun Enable auf 1 und anschließend wieder auf 0 hast du doch
einen Puls. Von 0 auf 1 auf 0 -> auf 1 auf 0 (zweiter Puls) ->auf 1 auf
0 (dritter Puls).
Da ist dein erster Schritt doch völlig überflüssig. Da setzt du Pegel an
die Pins die du im zweiten Schritt wiederholst.
Oder meinst du ingesamt nur drei mal Daten über TWI senden? Dann
bräuchtest du aber nur einmal die Adresse. So ganz werde ich da aus dir
leider nicht schlau.
Gib doch netterweise mal ein pseudo Code Beispiel vielleicht wird es
dann klarer.
Mr.Micro schrieb:> Ich arbeite zwar nie mit dem HD44780 aber UWE hat meiner Meinung nach> recht. Nur, handelt es sich bei seiner Variante ja eben auch um einen> Puls. Enable liegt doch in der Regel auf 0.
Adresse und R/W muss aber einige 10ns vor der steigenden Flanke von E
anliegen!
hinz schrieb:> Mr.Micro schrieb:> Ich arbeite zwar nie mit dem HD44780 aber UWE hat meiner Meinung nach> recht. Nur, handelt es sich bei seiner Variante ja eben auch um einen> Puls. Enable liegt doch in der Regel auf 0.>> Adresse und R/W muss aber einige 10ns vor der steigenden Flanke von E> anliegen!
Wäre dann nicht folgendes Szenario möglich?
mC sendet Start Signal
mC sendet Adresse
mC sendet höherwertiges Nibble (Enable 0)
mC sendet niederwertiges Nibble (Enable 1)
mC sendet mach ausreichend Wartezeit 0 Byte
mC sendet Stop Signal
Mr.Micro schrieb:> mC sendet höherwertiges Nibble (Enable 0)> mC sendet niederwertiges Nibble (Enable 1)
E hat nicht mit den Nibbles zu tun.
Wenn sich Adresse und R/W nicht geändert haben, dann kann der von mir
erwähnte 1) Schritt natürlich entfallen. Aber eben nur dann.
hinz schrieb:> Mr.Micro schrieb:> mC sendet höherwertiges Nibble (Enable 0)> mC sendet niederwertiges Nibble (Enable 1)>> E hat nicht mit den Nibbles zu tun.>> Wenn sich Adresse und R/W nicht geändert haben, dann kann der von mir> erwähnte 1) Schritt natürlich entfallen. Aber eben nurhinz schrieb:> Mr.Micro schrieb:> mC sendet höherwertiges Nibble (Enable 0)> mC sendet niederwertiges Nibble (Enable 1)>> E hat nicht mit den Nibbles zu tun.>> Wenn sich Adresse und R/W nicht geändert haben, dann kann der von mir> erwähnte 1) Schritt natürlich entfallen. Aber eben nur dann.
Aber wieso sollte sich denn die Adresse plötzlich ändern? Die dürfte fix
sein! Und wieso R/W?
So wie ich es sehe werden doch R/W, E, R/S und der Pegel für die
Hintergrundbeleuchtung zusammen mit eben dem höherwertigen Bzw.
niederwertigem Nibble (D7-4;3-0) jedes Mal übertragen. Solange ich also
bei jeder Datenübertragung den selben Wert für R/W nutze wird da nichts
verändert. Und würde ich R/W verändern wäre so oder so alles für die
Katz da ich von schreiben auf lesen wechseln würde.
Mr.Micro schrieb:> Aber wieso sollte sich denn die Adresse plötzlich ändern? Die dürfte fix> sein!
Adresse ist hier RS!
> Und wieso R/W?
Weil man nicht nur schreiben will?
hinz schrieb:> Mr.Micro schrieb:> Aber wieso sollte sich denn die Adresse plötzlich ändern? Die dürfte fix> sein!>> Adresse ist hier RS!>> Und wieso R/W?>> Weil man nicht nur schreiben will?
Du meinst also ob Befehls oder Datenregister. Jau das stimmt. Sehr
verwirrend wenn du vonnöten Adresse sprichst, wo es hier um TWI geht.
Ich dachte die ganze Zeit du willst die Slave Adresse jedes Mal
mitsenden.
Warum man allerdings während der Übertragung eines (halt nur zerhackt
durch TWI und 4 Bit Ansteuerung) Befehls das Register Bzw. den
Lese-Schreib Modus ändern sollte ist mir schleierhaft. Und das macht
wenn du es mal ehrlich bist auch keinen Sinn. Wieso sollte man nach
einem halben Display löschen Befehl plötzlich etwas vom Display lesen
wollen? In sofern ist dein erster Schritt also so wie Uwe sagte einfach
überflüssig.
Hi,
erst einmal etwas Grundsätzliches:
Wie ein funktionierendes ASM Programm zur Initialisierung eines LCD mit
HD44780-kompatiblen Controller aussehen kann, im angehängten ASM File.
OK. Sieht total aufgeblasen aus, aber das Programm wird ja später auch
eingebettet in das Programm, das das, was angezeigt werden soll,
"errechnet".
Es gibt LCDs, die haben "huckepack" ein I2C oder TWI Interface davor-
geschaltet. Die Initialisierung erfolgt aber nach wie vor über die
Pin-Konfiguration des LCD.
Siehe Bild 2.
(Dann haben einige AVRs das TWI Feature schon an Board, so dass sie wie
Timer UART etc. enabled werden können mit entsprechenden "Registern"
.Die heißen dann TWEN, TWISTO oder so. Das ist wohl nicht gemeint hier.)
Worum geht es jetzt hier genau. Nehme an, letztere LCD-Kombination.
Dann gibt es LCDs, die können von sich aus schon TWI:
Zum Bleistift:
https://www.lcd-module.de/fileadmin/pdf/doma/dogs104.pdf
Seite 4 .Ist aber ein anderer Controller!
"...Es kann dadurch bei größerer Buslast zu Signalverschleifungen und
unsauberen Pegeln kommen. Im Zweifelsfall sind zusätzliche Pull-Down
Widerstände erforderlich, oder es müssen zusätzliche Waits/NOP's
eingefügt werden..."
ciao
gustav
Karl B. schrieb:> Es gibt LCDs, die haben "huckepack" ein I2C oder TWI Interface davor-> geschaltet. Die Initialisierung erfolgt aber nach wie vor über die> Pin-Konfiguration des LCD.> Siehe Bild 2.
Genau so eines hat der TE.