Forum: Mikrocontroller und Digitale Elektronik LCD ST7066U Initialisierung?


von Olli (Gast)


Angehängte Dateien:

Lesenswert?

Hat schon jemand solch einen Controller zu seinem LCD gehabt?
Ich seh bei der Init nicht durch. Es soll ja mit dem HD44780 
pinkompatibel sein, was nat. nicht heißt, dass es auch 
Software-technisch genauso funktioniert.

Ich möchte es im 4-Bit Modus initialisieren:
Auszug aus dem Datenblatt:

INITIAL_START:
 CALL DELAY40mS
 MOV A,#38H         ;FUNCTION SET
 CALL WRINS_ONCE    ;8 bit,N=1,5*7dot
 CALL DELAY37uS
 MOV A,#28H         ;FUNCTION SET
 CALL WRINS_NOCHK   ;4 bit,N=1,5*7dot
 CALL DELAY37uS
 MOV A,#28H         ;FUNCTION SET
 CALL WRINS_NOCHK   ;4 bit,N=1,5*7dot
 CALL DELAY37uS
 MOV A,#0FH         ;DISPLAY ON
 CALL WRINS_CHK
 CALL DELAY37uS ...

Da stehen ja 8 bit Hex-Zahlen, aber ich habe nur 4 Leitungen zu den 
DB4-DB7, wie ist das zu verstehen?
Anbei noch eine Grafik, die das näher bringt.

Grüße Olli

von Olli (Gast)


Lesenswert?

Weiß keiner was damit gemeint ist?
Oder reicht es wenn ich nur das obere Byte schreibe?

MfG Olli

von Jörg X. (Gast)


Lesenswert?

AVR-Tutorial: LCD gesehen?
Die Bytes werden als zwei Hälften geschickt (Datanblatt gelesen?!), 
AUSSER natürlich dem ersten Byte, denn nach dem Reset sind die 
LCD-Controller im 8-Bit Modus, von diesem ersten Byte wird nur eine 
hälfte geschickt.

hth. Jörg

von Olli (Gast)


Lesenswert?

Das Tut hab ich mir schon 2x durchgelesen.

Ich hab mir die SubRoutine WRINS_NOCHK nicht richtig angeschaut, die 
geht in WRINS_ONCE weiter und da wird dann das zweite Nibble 
geschrieben.

Ist es eig. ratsam das in C(AVR Studio) umzuschreiben? Man könnte es ja, 
glaub ich, auch in Assembler schreiben mit "asm." oder so ähnlich.
Ich weiß nämlich noch nicht, wie ich das mit den Verzögerungszeiten in C 
realisiere, oder macht man das da auch mit Zählvariablen?

MfG Olli

von Jörg X. (Gast)


Lesenswert?

> Das Tut hab ich mir schon 2x durchgelesen.
aha?!

> Ich hab mir die SubRoutine WRINS_NOCHK nicht richtig angeschaut, die geht
> in WRINS_ONCE weiter und da wird dann das zweite Nibble geschrieben.
richtig! Zuerst wird WRINS_ONCE aufgerufen (wie in WRite INStruction, 
ein Mal) dann WRINS_NOCHK (WRIte INStruction, NO busyflag CHecK).

> Ist es eig. ratsam das in C(AVR Studio) umzuschreiben? Man könnte es ja,
> glaub ich, auch in Assembler schreiben mit "asm." oder so ähnlich.
hä? wenn du einen AVR in C programmierst solltest du es tun, wenn du 
einen anderen µC programmierst musst du was anderes machen (du hast mit 
keinem Wort erwähnt, was du eigentlich machst/willst).
Man könnte das mit Inline-Assembler lösen 
(http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Assembler_und_Inline-Assembler), 
das macht man aber nur, wenn man C und Assembler beherrscht.
Dir ist aber schon aufgefallen, dass der Beispiel-Code KEIN AVR 
Assembler ist? ;-)

> Ich weiß nämlich noch nicht, wie ich das mit den Verzögerungszeiten in C
> realisiere, oder macht man das da auch mit Zählvariablen?
beim AVR-GCC (winavr) mit _delay_us() oder _delay_ms() aus der 
<util/delay.h> (AVR-GCC-Tutorial). Zählvariablen funktionieren 
normalerweise nicht -- die werden vom Compiler wegoptimiert.

>>MfG Olli

hth. Jörg

von Olli (Gast)


Lesenswert?

>>hth. Jörg
ty

Woher wusstest du was die Kürzel(NOCHK...) bedeuten, ich konnte damit 
überhaupt nichts anfangen!

In AVR-Assembler habe ich noch nicht programmiert, wusste auch nicht, 
dass es da Unterschiede gibt!
Werd das dann in C schreiben.. danke für den Tipp mit delay.h!

Olli

von Jörg X. (Gast)


Lesenswert?

> Woher wusstest du was die Kürzel(NOCHK...) bedeuten, ich konnte damit
> überhaupt nichts anfangen!
war geraten...
 Nee, im ernst: im Datenblatt ist doch das Diagramm mit dem Ablauf. Da 
steht z.B. "BF[d.h. Busy-Flag] cannot be checked before this 
instruction", daher das Kürzel (NO-)CHK für (kein) CHecK, außerdem die 
Bits RW und RS für Read/Write und RegisterSelect -- RS sagt dem Display 
ob Daten oder Befehle ("INStructions") anliegen -- und schließlich sthet 
da, ob ein oder zwei Mal Daten übertragen werden.

> In AVR-Assembler habe ich noch nicht programmiert, wusste auch nicht,
> dass es da Unterschiede gibt!
Jaja -- Assembler (dt.: "Maschinensprache") ist doch bei jeder 
Prozessor-Familie (ARM, AVR, x86/IA-32, PIC(gibts mehrere verschiedene), 
msp430, etc. ...) anders.

 Zusätzlich haben auch AVR-Studio-Assembler(*.asm-Datei), 
AVR-GCC-Inline-Assembler (in .c-/.h-Dateien) und AVR-GAS (in extra 
Assembler-Dateien, *.S) (leicht) unterschiedliche Synthax...

hth. Jörg

von Olli (Gast)


Lesenswert?

Vielen Dank!
Werd mich gleich mal ransetzen, mal sehen ob's klappt.. die hardware 
muss ja auch ncoh "initialisiert" werden!

Olli

von Olli (Gast)


Lesenswert?

Ich hab noch gar nicht richtig angefangen, und schon die ersten 
Probleme!

1.nibbles tauschen. hab es so versucht, funktioniert aber nicht:

        void swap(U8 a, U8 b) {
           a = (((b >> 4) & 0x0F) | ((b << 4) & 0xF0));
        }

2.Für die Daten/Befehle habe ich nur einen halben Port frei(die unteren 
4 Bits)(benutze den 4-Bit Modus), die anderen dürfen nicht verändert 
werden, da hilft einem das |= bzw. &= nicht, weil man im Befehl auch 0 
und 1 zusammen hat(z.B 00001011).
Wie macht man denn so etwas? Kann man vielleicht die Bits einzeln aus 
der Variablen ziehen und auf die Pin's schreiben?

ich hoffe ihr habt Tipps für mich und könnt das nachvollziehen, was ich 
hier geschrieben hab.

Gruß Olli

von Olli (Gast)


Lesenswert?

Ich hätte einen Lösungsansatz für 2.

PortPin0-3 auf 0 setzen und dan Port&=Daten/Befehl

Das ist aber auch nich das Wahre, oder?

Olli

von Jörg X. (Gast)


Lesenswert?

1
//! Hae?
2
void swap(U8 a, U8 b) {
3
           a = (((b >> 4) & 0x0F) | ((b << 4) & 0xF0));
4
        }
5
6
// Probier's so...
7
U8 swap( U8 b)
8
{
9
    return ((b >> 4) | (b << 4));
10
}
Ist aber doch unnötig, du brauchst ja nicht wirklich den "swap".
schau dir mal z.B. die LCD-Lib von jump.to/fleury an...

hth. Jörg

von Jörg X. (Gast)


Lesenswert?

und zu 2):
1
//wenn in der Variablen nur noch was im High-Nibble steht:
2
LCD_PORT = var_mit_data |(LCD_PORT & 0x0F);
...

von Olli (Gast)


Lesenswert?

..nochmal danke, ich hätte wohl noch etwas länger daran gesessen, und 
dann hätt's auch nicht so elegant ausgesehen.
Ich seh jetzt auch den Fehler bei meinem swap, der Wert(a) wird nicht 
zurück gegeben..

von Olli (Gast)


Lesenswert?

Noch zwei Kleinigkeiten, die mir nicht ganz klar sind:

1. Das E-Bit zur Datenübernahme wird im Code aus dem Datenblatt gesetzt, 
bevor die neuen Daten an den Ausgabeport gelegt werden, d.h. ja, dass im 
ersten Moment noch die alten anliegen.
Hat das Vorteile/Nachteile, ist das überhaupt richtig?
______________________________________________________________________ 
_
WRINS_ONCE:
ANL A,#F0H
CLR RS
CLR RW
SETB E
MOV P1,A
CLR E
MOV P1,#FFH ;For Check Bus Flag
RET
______________________________________________________________________ 
_

2. Ich dachte dass alle LCD-Controller ASCII-konform sind, im Datenblatt 
zu meinem hab ich insgesamt 4 Tabellen gefunden, die sich alle 
unterscheiden. Eins vom Display, und drei vom Controller mit 
verschiedenen ROM-Codes:0A,0B und 0E ???
Muss ich dann alles selber definieren, oder gibt es Bibliotheken für 
einzelne Controller?

Gruß Olli

von Jörg X. (Gast)


Lesenswert?

> 1. Das E-Bit zur Datenübernahme wird im Code aus dem Datenblatt gesetzt,
> bevor die neuen Daten an den Ausgabeport gelegt werden, d.h. ja, dass im
> ersten Moment noch die alten anliegen.
Das Display übernimmt die Daten auf der fallenden Flanke von E. Die 
genauen Zeiten, wie lange welche Signale an/aus sein müssen steht (bei 
mir) Seite 30 im ST7066U datenblatt (die Tabelle dazu ist 3 Seiten 
weiter hinten).

> Hat das Vorteile/Nachteile,
das Display ignoriert ganz sicher alle Daten, solange E =1 ist.
> ist das überhaupt richtig?
bestimmt, es wäre (ist) sehr ungünstig, wenn Codebeispiele aus dem 
Datenblatt nicht funktionieren..

> 2. Ich dachte dass alle LCD-Controller ASCII-konform sind,
Warum sollten sie? Aber meistens ist nur ein offset zu berechnen...

> im Datenblatt zu meinem hab ich insgesamt 4 Tabellen gefunden, die sich
> alle unterscheiden. Eins vom Display, und drei vom Controller mit
> verschiedenen ROM-Codes:0A,0B und 0E ???
Probiers aus? Sende dem Display mal alle, in den Tabellen erlaubten, 
Zahlen (sowas wie "for(i=0, i<200, i++) lcd_putc(i);"...). Und schau 
welche Tabelle das sein könnte.

> Muss ich dann alles selber definieren,
Könnte schwierig werden, eine (interne) ROM-Tabelle selber zu machen ;-)

> oder gibt es Bibliotheken für einzelne Controller?
Wie meinst du das?

hth. Jörg

von Olli (Gast)


Angehängte Dateien:

Lesenswert?

>> oder gibt es Bibliotheken für einzelne Controller?
>Wie meinst du das?

Ich dachte an eine Bib in der die einzelnen Zeichen mit ihrem Code 
definiert werden!
z.B. #define A 0b01010100
..., das meinte ich auch mit selber definieren, quasi die Tabelle in 
eine Bibliothek packen.

Im Anhang die timing characteristic:
..die besagt doch, das die eingehenden Daten nach einer gewissen Zeit 
nach steig. Flanke von E "gültig" sind und sogar noch nach einer 
gewissen Zeit nach der fallenden Flanke! Oder liege ich da falsch?
Aber du hast schon recht, wäre schon gut, wenn der Code im Datenblatt 
richtig ist,.. aber man weiß ja nie.. ;)

Gruß Olli

von Jörg X. (Gast)


Lesenswert?

Sry, hab mir jetzt erst die Character tables angeschaut: die Zahlen und 
Buchstaben sind in allen drei Tabellen im Datenblatt ASCII kompatibel!
 (und du hattest wahrscheinlich auch nicht vor, nichtdruckbare Zeichen 
anzuzeigen ;)
> Ich dachte an eine Bib in der die einzelnen Zeichen mit ihrem Code
> definiert werden!
> z.B. #define A 0b01010100
> ..., das meinte ich auch mit selber definieren, quasi die Tabelle in
> eine Bibliothek packen.
Würde auch nicht funktionieren, du kannst den Character ROM des LCD 
nicht überschreiben. Du kannst nur ein paar (8Stk. bei 8x5 Pixel) 
eigene Zeichen definieren, falls notwendig.

> Im Anhang die timing characteristic:
> ..die besagt doch, das die eingehenden Daten nach einer gewissen Zeit
> nach steig. Flanke von E "gültig" sind und sogar noch nach einer
> gewissen Zeit nach der fallenden Flanke! Oder liege ich da falsch?
Das sind alles Minimum-angaben:
 - E muss für mindestens 460ns (tPW) auf highpegel sein
 - Die Daten müssen 80ns (tDSW) vor der fallenden Flanke anliegen
 - und min. 10ns (tDH) nach der fallenden
 - RS und RW können offenbar gleichzeitig mit der steigenden Flanke 
von E gesetzt werden (tAS)
 -  beim Lesen (z.B. busyflag) liegen die Daten vom Display max. 320ns 
nach der steigenden Flanke von E an (tDDR)
(meine Zahlen gelten offenbar für Vcc=2,7V, da du wahrscheinlich 5V 
benutzt werden die zeiten noch kürzer, vgl. Tabelle s33.)

hth. Jörg
ps.: MERKE: bei 20MHz dauert ein µC Takt 50ns...

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.