LCd Initialisierung schlägt fehl

OP #5284181
Lesenswert?

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
void lcd_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
25
twi_send_data(0x00|(1<<LCD_D7)| (1<<LCD_E) | (1<<LCD_LIGHT));  //
26
twi_stop();                            //
27

28
twi_start(SLA_W);                        //
29
twi_send_data(0x00 | (1<<LCD_E) | (1<<LCD_LIGHT));        //Display aus
30
twi_send_data(0x00 |(1<<LCD_D7)| (1<<LCD_E) | (1<<LCD_LIGHT));  //
31
twi_stop();                            //
32

33
twi_start(SLA_W);                        //
34
twi_send_data(0x00 | (1<<LCD_E) | (1<<LCD_LIGHT));        //Display löschen
35
twi_send_data(0x00 | (1<<LCD_D4) | (1<<LCD_E) | (1<<LCD_LIGHT));//
36
twi_stop();                            //
37

38
twi_start(SLA_W);                            //
39
twi_send_data(0x00|(1<<LCD_E)|(1<<LCD_LIGHT));              // Kursor nach rechts wandernd, kein Display Shift
40
twi_send_data( 0x00|(1<<LCD_D6)|(1<<LCD_D5)|(1<<LCD_E)|(1<<LCD_LIGHT));  //
41
twi_stop();                                //
42

43
twi_start(SLA_W);                                //
44
twi_send_data(0x00 | (1<<LCD_E) | (1<<LCD_LIGHT));                //Display ein
45
twi_send_data(0x00 | (1<<LCD_D7)  | (1<<LCD_D6) | (1<<LCD_E) | (1<<LCD_LIGHT));  //
46
twi_stop();                                    //
47
}
OP #5284248
Lesenswert?

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.
OP #5284252
Lesenswert?

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.
OP #5284293
Lesenswert?

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?
#5284297
Lesenswert?

hinz schrieb:
> Dir ist klar, dass ein einzelner Schreibzyklus an das eigentliche die
> Übertragung von 3 Bytes via I2C erfordert?


Zur Vertiefung ein wenig Literatur:

https://s-huehn.de/elektronik/wohnuhr/wohnuhr.htm
https://s-huehn.de/elektronik/wohnuhr/wohnuhr-v115-std.zip

In File
wohnuhr.asm
Ab Label:

w3actv

ist TWI in ASM code ausformuliert.

Das kann man auch umschreiben für LCD.

ciao
gustav
Gast #5284313
Lesenswert?

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...
Gast #5284332
Lesenswert?

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...
Gast #5284336
Lesenswert?

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
Gast #5284430
Lesenswert?

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.
Gast #5284438
Lesenswert?

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
Gast #5284455
Lesenswert?

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 nur

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 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.
Gast #5284462
Lesenswert?

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.
#5284772
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren