Forum: Projekte & Code i2c TWI LCD 4Bit PCF8574 HD44780 ATmega8 Assembler


von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Geschätztes Forum,

ein kleines Beispiel Version1,
wie ein TWI/I2C LCD im 4 Bit-Modus initialisiert werden kann.

Nach Programmstart wird ein LED-Test durchgeführt und der TWI-Slave 
angesprochen. Die LCD-Hintergrundbeleuchtung wird mal kurz dunkel.

Bei Error leuchtet LED-Rot (z.B. Slave antwortet nicht).

Nun wird das LCD auf den 4 Bit-Modus umgeschaltet und die
LCD-Hintergrundbeleuchtung mal kurz dunkelgetastet
und ein Begrüßungstext angezeigt.

War der Programmstart erfolgreich, dann leuchtet die grüne LED.


-----------------------------------------------------------------

Die Loop-Schleife:

Ein 4 Byte-Zähler zählt jeden Schleifendurchlauf und
zeigt das Ergebnis dezimal und hexadezimal an.

Sieht lustig aus :-)

Im Normalfall leuchtet grün und gelb flackert.

Leuchtet rot, dann stimmt(e) etwas nicht....

-----------------------------------------------------------------

Alle Vorgänge sind stark verlangsamt,
kann aber z.B. durch Veränderung
TWI_BIT_RATE und TWI_PRESCALER beschleunigt werden.


µC Takt: 1MHz

Anmerkung:

Zuerst werden spezielle LCD-Pins gesetzt (D4, D5, D6, D7, RS...)
und an den Slave gesendet
erst dann Erfolgt die Sendung des Enable-Impuls,
Sendung Enable L und Sendung Enable wieder H.

Geht vielleicht auch besser, ist aber die sichere Variante ^^




Für konstruktive Hinweise bin ich sehr dankbar.

Bernhard

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

1
  clr temp1          ; NULL          
2
  sbrc temp,7          ; Sprung wenn Bit7=NULL  
3
  sbr temp1,BIT_D7      ; Bit 7 setzen      
4
  sbrc temp,6          ; Sprung wenn Bit6=NULL  
5
  sbr temp1,BIT_D6      ; Bit 6 setzen      
6
  sbrc temp,5          ; Sprung wenn Bit5=NULL  
7
  sbr temp1,BIT_D5      ; Bit 5 setzen      
8
  sbrc temp,4          ; Sprung wenn Bit4=NULL  
9
  sbr temp1,BIT_D4      ; Bit 4 setzen      
10
  sbr temp1,BIT_RS      ; RS (high) !!!      
11
  sbr temp1,BIT_EN      ; EN (high)        
12
  sbr temp1,BIT_LED      ; LED on(high)
kommt mir reichlich umständlich vor.

warum nicht
1
mov temp1, temp
2
andi temp1, 0xF0
3
sbr temp1, BIT_RS|BIT_EN|BIT_LED ; "ori"

von Wastl (hartundweichware)


Lesenswert?

Bernhard S. schrieb:
> Für konstruktive Hinweise bin ich sehr dankbar.

Damit mehr Leute sich angesprochen fühlen, das Ganze in C
progammieren. Assembler bringt bei diesen langsamen LCDs
keine Geschwindigkeitsvorteile, nicht einmal wenn es gilt
die I2C Hürde zu überwinden.

Beispiele in C gibt es allerdings zuhauf.

von Achim H. (pluto25)


Lesenswert?

Bernhard S. schrieb:
> die sichere Variante

In der Tat großzügige 'wait_10ms'
Jedoch nach dem Cls braucht es wirklich eine Pause: ca 400µs (ertestet) 
besser 2ms (save).
Auch beim Kaltstart wäre eine Wartezeit (40ms bei 3,3V / 15ms bei 5V) 
vor dem ersten Befehl sicher.
Das Lcd übernimmt die Daten bei der h/L Flanke des Enable. Es reicht dem 
Pcf die Daten nur zweimal zu übergeben. Das erste mal mit E=High und 
dann mit E=Low. Das halbiert die TWI Ausgaben.
Auch wenn es lästig ist, wäre es nett das Backlightbit mit zu 
berücksichtigen.
Andererseits ist das Flackern ein 'nicht abgestürzt' Zeichen ;-)

von Bernhard S. (bernhard)


Lesenswert?

Achim H. schrieb:
> Das Lcd übernimmt die Daten bei der h/L Flanke des Enable. Es reicht dem
> Pcf die Daten nur zweimal zu übergeben. Das erste mal mit E=High und
> dann mit E=Low. Das halbiert die TWI Ausgaben.

Da gebe ich Dir Recht,

die beiden Datenbytes an PCF8574 (RS+oberes Nibbles + RS+unteres 
Nibbles)

werden mit Enable= H übergeben.

Und schlussendlich wird RS + Enable= L gesendet.

In Summe drei Datenbytes
(RS+oberes Nibbles + RS+RS+unteres Nibbles + RS+Enable).

: Bearbeitet durch User
von Achim H. (pluto25)


Lesenswert?

Das hab ich nie versucht, sie bekamen immer ein Enable=Low nach jeder 
Daten(Nibble)Änderung. (Vier Sendungen pro Zeichen/Anweisung)
Drei wären nicht schlecht: 25% Beschleunigung/weniger Arbeit für den 
Mega :-)
Jedoch bin ich da skeptisch. Die hier an einem (halben)Port hängen sind 
völlig unbeeindruckt von den Signalen auf ihren Datenleitungen 
(Doppelbelegung), solange keine H/L Flanke des Enable passiert.

von Bernhard S. (bernhard)


Lesenswert?

Achim H. schrieb:
> Jedoch bin ich da skeptisch. Die hier an einem (halben)Port hängen sind
> völlig unbeeindruckt von den Signalen auf ihren Datenleitungen
> (Doppelbelegung), solange keine H/L Flanke des Enable passiert.

...intertesanter Gedankengang, gefällt mir :-)

Hab's gleich mal getestet !

Bei jeder Sendung, also bei jedem Datenbyte muss RS immer korrekt 
gesetzt sein, sonst zeigt das LCD sehr seltsame Erscheinungen.

1. Datenbyte - oberes  Nibbles + RS + RW=L + Enable= H
2. Datenbyte - wie 1.Datenbyte aber Enable= L
3. Datenbyte - unteres Nibbles + RS + RW=L + Enable= H
4. Datenbyte - wie 3.Datenbyte aber Enable= L

...fertsch

Also 4 Datenbytes werden benötigt :-)

: Bearbeitet durch User
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Version 2

In dieser Version darf kein weiterer TWI-Slave angesprochen oder

eine TWI-Stop Anweisung ausgeführt werden !


Diese Version, ohne permanenten TWI-Start, spart Zeit und

die Datenübertragung ist etwas flotter :-)


Bei jedem Ascii-Zeichen oder Kommando (z.B. LCD-clear) sind

vier TWI-Bytes erforderlich.

1.Bytes oberes  Nibbles
2.Bytes Enable H->L
3.Bytes unteres Nibbles
4.Bytes Enable H->L

Mögliche Ursache:

Der Enable H->L Impuls am PCF ist zu schnell,

das Display kann die Steuersignale nicht schnell genug verarbeiten und

wird vom Enable überrascht...

Eventuell könnte ein RC-Glied am Enable-Pin diesen Effekt beseitigen,

damit zuerst die Daten- und Steuerpins ausgewertet sind,

bis einige µs später Enable zubeißt.



Würde die RC-Variante funktionieren, dann wären

nur noch 2 TWI-Bytes erforderlich :-)

: Bearbeitet durch User
von Achim H. (pluto25)


Lesenswert?

Um mit zwei Bytes aus zu kommen müsste die Hardware hinter dem Pcf 
geändert werden. Denkbar wäre den Enable zu toggeln so das bei jeder 
Änderung eine High-Low Flanke zum Lcd erzeugt würde.
Dem Pcf "endlos" Daten zu senden geht recht gut. Auch wenn andere Slaves 
vorhanden sind. Der Code weiss ja mit wem er spricht. So ist es ohne 
weiters möglich z.B ein Start, Lese Rtc (2-63?Bytes), Stop , Start, 
Schreibe Lcd, 34Bytes(Locate,Uhrzeit), Stop, Start, weiterer Slave, .... 
Stop.
Das RS (und auch Rw) müssen natürlich eindeutig sein. Es kann ja nicht 
ahnen ob Daten oder Anweisungen folgen ;-)
Ich hab die neue Version überflogen. Vielleicht doch mal Enrst's 
Vorschlag überdenken?
Mich würden die WAIT_10ms nach jedem Byte stören. In 10ms könnte eine 
Zeile voll geschrieben sein. Da das Cls eine eigene Routine hat können 
dort die 2ms rein. Bei anderen Anweisungen/Daten ist das Lcd schneller 
als der Pcf empfangen kann. Da sind keine Waits nötig (abgesehen vom 
Init)
Das Home (0x02) braucht auch ein wenig Zeit (140µs ertestet/1,5ms save)

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.