Hallo zusammen,
ich wollte einmal aus Lernzwecken mir eine LCD Ansteuerung selbst
schreiben.
Das ganze soll im 4 Bit Modus laufen. Meinen Code habe ich angehängt.
Das Problem ist das nichts passiert. Ich hab mir auch den LCD Teil des
Tutorials angeschaut nur leider werde ich nicht ganz daraus schlau. Was
bedeutet denn in der lcd_init Routine das 3malige wiederholen des einen
Befehls. Bei mir im Datenblatt des LCD´s kann ich mir damit keinen Reim
darauf machen.Ich benutze ein 4x16 LCD mit HD44780 Controller einen
AT90S4433 mit 4Mhz.
Grüße Gerd
Hallo.
kleiner tipp.... der modus wird nicht im Daten Modus, sondern im
Befehlsmodus gesetzt. Ich gehe davon aus, dass du an pin 5 den E pin des
display hast. mit welchem pin schaltest du RS des displays ? dieser pin
schaltet zwischen befehls und datenmodus um. Dann.... Die konfiguration
der ports / Ein Ausgang setzt man möglichst ganz am anfang nur 1 mal,
nicht immer wieder im laufenden programm.. jedenfalls sooo wird dein lcd
niemals funktionieren.
Ich hab die Datei nochmal mit den Belegungen erweitert.
Der Enable ist an PB5 und RS an PB4.
Ich verstehe nicht was du meinst mit den modus setzt man im Datenmodus.
Ist RS low dann ist man doch im IR Register des Controllers,oder??? Und
welchen Ausgang setze ich denn immer wieder im Programm?? Den PORTB als
Ausgang wird doch nur einmal gesetzt.
Ich bin noch ein blutiger Anfänger also habt bitte Geduld mit mir.
Grüße Gerd
Du machst nur immer den E eingang high mit enable, welcher nur die Daten
übernimmt, während RS HIGH sein muss um etwas auf dem Display
darzustellen, das gesendete Zeichen also zu übernehmen und RS muss LOW
sein um dem Display einen Befehl zu senden, also eben LOW um den MODUS
im Display einzustellen.
Also:
RS LOW --- Befehl an Display. Befehl wird mit E = High( lcd enable )
übernommen.
RS HIGH --- Die anliegenden Daten werden auf dem Display augegeben, wenn
E High gemacht wird.
Irgendwie komm ich da jetzt durcheinander.
ldi temp,0b00000010 ;4Bit Modus im 8Bit Modus setzen
out PORTB,temp
Da ist doch PB4 low=Befehl an Display
Danach kommt ein Enable->Befehl übernehmen.
Von Zeichen darstellen auf dem Display ist bei dieser INIT Routine noch
nirgends die Rede
sorry.. so genau hab ich mir deinen code nicht angeschaut... ich bezog
mich nur auf deine aussage NICHTS PASSIERT.... daher meinte dass du
nichts angezeigt bekommst...
Ich hab doch aber das LCD an die unter 4 PINs angeschlossen die oberen
beiden Ausgänge sind ja low->wegen RS.
Ich kann ja schlecht nur 4 bit übertragen
Deswegen wird das ganze ja auch in 2er Schritten übertragen, was ich mit
den Kommentaren sagen will.
Das Display erwartet aber einen gültigen 8 Bit wert. wenn Du nur 4
leitungen angeschlossen hast überträgst du auch nur 4 bits. die
restlichen 4 bits musst du auch noch senden, über die gleichen
portleitungen. dazu musst du den oberen und unteren nibble vertauschen.
mit dem Swap befehl.
Beispiel:
10110001 willst du an das display senden
mit dem out befehl werden aber nur die bits übertragen die an den 4
portleitungen, die am lcd angeschlossen sind anliegen ( mal von der
maskierung abgesehen ) also in deiner version, die 0001. dann musst du
mit dem swap befehl die nibbles vertauschen. dann sieht der wert so aus:
00011011 also umgekehrt. Dann nochmal mit dem out befehl die restlichen
4 bits senden, also die 1011.
Da Du aber am selben port noch E und RS hast musst du mit dem ANDI
befehl die 4 bits maskieren die du senden willst, ansonsten wird der
jeweils obere nibble auch die beiden pins beeinflussen, was ja nicht
sein soll bzw darf. Wenn die daten im register temp stehen, also ANDI
temp, 0b00001111 da du ja nur die unteren 4 bits ausgeben willst.
ich hoffe das war etwas ausführlicher und der groschen fällt jetzt :)
Ich glaube wir reden ein wenig aneinander vorbei.
Ich hab mir die Lösung des Problems auch im Tutorial angeschaut und ich
fand das die ganze Sache mit den Nipples vertauschen aufwendiger
ist.(Naja Geschmacksache)Deshalb sende ich ja das höher wertige Nipple
zuerst und danach das nieder wertigere. Jeweils die oberen 4 Bits
bleiben low da ja mein LCD an den unteren PINS hängt.Wenn ich also den
Befehl 0010 1100 übertragen will wird zuerst das obere Nipple
gesendet(0000 0010) und danach das niedere Nipple (0000 1100). Korrigier
mich bitte wenn ich einen Denkfehler habe
Ja, genau, so kann mans auch machen was ich aber wieder umständlicher
finde.. aber ist ansichtssache.... nach genauerem hinschauen glaube ich
eher das programm bleibt in deiner 12ms schleife hängen..... das
register r16 bleibt 0x00 und somit springt er immer in der schleife...
weil er nie den wert den du mit cpi vergleichen willst erreicht.
ich hab das mal auf die schnelle etwas abgeändert.. lass das mal drüber
laufen und schau mal was mit deinem lcd passiert. habs jetzt nicht
getestet aber versuch mal und sag mal bescheid ob mehr passiert, wenn
auch nichts angezeigt wird :)
Hi!
So ein Durcheinander habe ich lange nicht gesehen.
@Voyager9
ldi temp,0b00000011
Das ist 8-Bit Init!!!!!
Musst schon ldi temp,0b00000010 schreiben.
Und Gerd, 3x ist schon richtig, steht jedenfalls im Datenblatt. Was ist
mit R/W und den restlichen DB's, auf GND??? Ich hoffe jedenfalls.
Kontrast ok?(beim Einschalten Balken?)
MFG Uwe
Hallo Uwe,
R/W und restliche DB´s sind auf GND. Der Kontrast ist auch OK. Die
Balken hab ich auf dem Display.
Aber was meinst du mit "3x ist schon richtig".
Meinst du damit dass im Tutorial 3x der gleiche Befehl am Anfang
gesendet wird? Ich kann diesen Befehl nicht nachvollziehen. Das steht
auch nicht so im Datenblatt(oder habs nicht gefunden). Das ganze
geschieht doch noch im 8Bit Modus. Danach wird doch erst der 4Bit Modus
eingeschaltet.
Kannst du mir sagen für was die 3 Befehle am Anfang sind??
Grüße Gerd
Hi!
Also entweder hast du ein anderes Datenblatt oder du übersiehst was. 3x
die Starteinstellung DB5/4=10 senden und dann geht das eigentliche Init
erst los.N=1F=0->Kursor+Displ ein-> Displ.+Ram Reset.
Ich habe gerade gesehen das du zu viele Pausen machst. Es müssen immer 8
bit kommen bzw.2x4Bit hintereinander.
Du bekommst das schon noch hin, nur Mut und schön lesen.
MFG Uwe
Hallo Uwe,
ich habs hinbekommen.
Was für eine schwere Geburt!!!
Du hattest recht ich hab mich auf die Anweisungen in der Tabelle
versteift und total übersehen das man bevor das init losgeht ersteinmal
den einen Befehl 3x wiederholen muss.
Allerdings hatte ich noch einen Fehler den ich mir nicht erklären kann.
Ich hab immer wieder das TIFR Register ausgelesen und nachgeschaut ob
der Timer schon übergelaufen ist. Das ging auch die ersten 4 Schleifen
gut. Danach hab ich allerdings in meinem temp Register(wohin ich das
TIFR eingelesen hatte) 0x0A stehen also 0b00001010. D.h. das ICF1 Flag
war dort ebenfalls gesetzt. Warum weiß ich nicht. Ich hab mit dem Timer1
doch garnichts gemacht.
Die Zeiten hab ich auch hochgesetzt das auch ja alles klappt. Das kann
man jetzt noch verfeinern ;) Den Code hab ich nochmals angehängt.Wenns
jemand interressiert. Vielleicht kann mir ja jemand noch mein Phänomen
mit den TIFR Register erklären.
Vielen Dank an alle die mir geholfen haben.
Grüße Gerd
Eine eigene Frage?
Dieser Thread ist über 23 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.