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
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
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
> 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
>>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
> 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
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
..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..
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
> 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
>> 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
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...