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
Weiß keiner was damit gemeint ist? Oder reicht es wenn ich nur das obere Byte schreibe? MfG 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
Vielen Dank! Werd mich gleich mal ransetzen, mal sehen ob's klappt.. die hardware muss ja auch ncoh "initialisiert" werden! Olli
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
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
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
und zu 2):
1 | //wenn in der Variablen nur noch was im High-Nibble steht:
|
2 | LCD_PORT = var_mit_data |(LCD_PORT & 0x0F); |
...
..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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.