Ich habe das Programm aus dem Turorial mit Win AVR ausprobiert.
Es klappt in der Simulation. (LCDSIM)
Ich habe es auf meinen Atmega32a übertragen und mein Display
angeschlossen.
Doch nix tut sich.
Es leuchtet nur blau und 1 & 3 Zeile sind voll ausgefüllt.
Das ist ja normal, wenn noch keine Daten anliegen.
Hatte jemand schonmal das Problem?
Gruß
Marius
Marius schrieb:> Hatte jemand schonmal das Problem?
Schon viele :-)
Wie schnell ist dein µC getaktet.
Die Routinen im Tutorial sind für 4Mhz ausgelegt. Wenn dein µC langsamer
läuft ist das kein Problem. Nur schneller sollte er nicht sein.
ich muss dazu sagen ich habe .include "m8def.inc" durch .include
"m32def.inc" ersetzt.
Das es aber im Simulator geht denke ich mal ich hab nix falsch gemacht.
Muss man denn bei der übertragung mit AVR Studio etwas beachten?
Ich habe mal ein C-File bei dem Port B Pin 1 blinkt getestet.
Aber des LCD will irgendwie noch nichtmal initialisieren.
Nachtrag:
Es muss doch irgendwen geben, der einen Atmega32a ein LCD mit KS0066
Controller und Avr Studio das oben genannte Programm ausprobiert hat.
Ich finde hier nämlich im Forum nichts darüber.
:-(
Vielen Dank für eine Antwort
Gruß
Marius
Diese LCD-Routine ist für einen HD44780-Controller.
Der KS0066 wird, soweit ich mich recht erinnere, etwas anders
initialisiert.
Mit der Suche solltest du aber hier einige Routinen für den KS0066
finden.
Oder das Datenblatt studieren.
Thomas
Also ich werde aus den Beiträgen nicht schlau.
Fast alles bezieht sich auf C.
Irgendwer muss doch mal in Assambler mit dem Atmega32a und einem LCD mit
KS0066 4x20 angesteuert haben und könnte das mal Posten.
In dem Datenblatt bei Farnell werde ich auch nicht schlau.
http://www.farnell.com/datasheets/31757.pdf
Gruß
Marius
Ja das habe ich gefunden.
Nun weiß ich noch nichtmal ob der Rest richtig ist:
lcd_enable
rcall lcd_command
Ich weiß nicht wo ich anfangen soll...
Ich bin mittlerweile richtig frustriert.
Wie soll ich denn sehen wo der Fehler sitzt?
P.S. die unter powerupwait: aufgeführten Zeilen sind noch nicht an das
KS0066 angepasst.
Aber irgendwer muss es ja schonmal mit einem ks0066 im 4-bit Modus
getestet haben.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LCD-Routinen ;;
;; ============ ;;
;; (c)andreas-s@web.de ;;
;; ;;
;; 4bit-Interface ;;
;; DB4-DB7: PD0-PD3 ;;
;; RS: PD4 ;;
;; E: PD5 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.equ LCD_PORT = PORTD
.equ LCD_DDR = DDRD
.equ PIN_E = 6
.equ PIN_RS = 4
;sendet ein Datenbyte an das LCD
lcd_data:
mov temp2, temp1 ; "Sicherungskopie" für
; die Übertragung des 2.Nibbles
swap temp1 ; Vertauschen
andi temp1, 0b00001111 ; oberes Nibble auf Null setzen
sbr temp1, 1<<4 ; entspricht 0b00010000 (Anm.1)
out PORTD, temp1 ; ausgeben
rcall lcd_enable ; Enable-Routine aufrufen
; 2. Nibble, kein swap da es
schon
; an der richtigen stelle ist
andi temp2, 0b00001111 ; obere Hälfte auf Null setzen
sbr temp2, 1<<4 ; entspricht 0b00010000
out PORTD, temp2 ; ausgeben
rcall lcd_enable ; Enable-Routine aufrufen
rcall delay50us ; Delay-Routine aufrufen
ret ; zurück zum Hauptprogramm
; sendet einen Befehl an das LCD
lcd_command: ; wie lcd_data, nur RS=0
mov temp2, temp1
swap temp1
andi temp1, 0b00001111
out PORTD, temp1
rcall lcd_enable
andi temp2, 0b00001111
out PORTD, temp2
rcall lcd_enable
rcall delay50us
ret
; erzeugt den Enable-Puls
;
; Bei höherem Takt (>= 8 MHz) kann es notwendig sein,
; vor dem Enable High 1-2 Wartetakte (nop) einzufügen.
; Siehe dazu Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
lcd_enable:
sbi PORTD, 5 ; Enable high
nop ; 3 Taktzyklen warten
nop
nop
cbi PORTD, 5 ; Enable wieder low
ret ; Und wieder zurück
; Pause nach jeder Übertragung
delay50us: ; 50us Pause
ldi temp1, $42
delay50us_:dec temp1
brne delay50us_
ret ; wieder zurück
; Längere Pause für manche Befehle
delay5ms: ; 5ms Pause
ldi temp1, $21
WGLOOP0: ldi temp2, $C9
WGLOOP1: dec temp2
brne WGLOOP1
dec temp1
brne WGLOOP0
ret ; wieder zurück
; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
ldi temp3,50
powerupwait:
rcall delay5ms
dec temp3
brne powerupwait
ldi temp1, 0b00000011 ; muss 3mal hintereinander
gesendet
out PORTD, temp1 ; werden zur Initialisierung
rcall lcd_enable ; 1
rcall delay5ms
rcall lcd_enable ; 2
rcall delay5ms
rcall lcd_enable ; und 3!
rcall delay5ms
ldi temp1, 0b00000010 ; 4bit-Modus einstellen
out PORTD, temp1
rcall lcd_enable
rcall delay5ms
ldi temp1, 0b00100000 ; 4Bit 2 Zeilen 5x8
rcall lcd_command
ldi temp1, 0b00001100 ; Display ein Cursor aus
kein Blinken
rcall lcd_command
ldi temp1, 0b00000100 ; inkrement / kein Scrollen
rcall lcd_command
ret
; Sendet den Befehl zur Löschung des Displays
lcd_clear:
ldi temp1, 0b00000001 ; Display löschen
rcall lcd_command
rcall delay5ms
ret
; Sendet den Befehl: Cursor Home
lcd_home:
ldi temp1, 0b00000010 ; Cursor Home
rcall lcd_command
rcall delay5ms
ret
Marius schrieb:> Ja das habe ich gefunden.>> Nun weiß ich noch nichtmal ob der Rest richtig ist:>> lcd_enable> rcall lcd_command
wenn deine tatsächliche Pinbelegung mit der im Programm angenommenen
übereinstimmt, sollte das passen. Du hast doch das Datenblatt, sieh nach
ob die Datenübertragung da dazupasst!
Aber soweit ich weiß, unterscheiden sich die KS nur in der Initsequenz
ein wenig von den HD und das wars dann schon.
> Ich weiß nicht wo ich anfangen soll...
Indem du den Code analysierst und mit dem vergleichst was im Datenblatt
als Ablauf gefordert ist.
> Ich bin mittlerweile richtig frustriert.> Wie soll ich denn sehen wo der Fehler sitzt?
Tja. So ist das nun mal in der Programmierung.
Es gibt ganz selten Fehler, die 'bitte hier' rufen.
Den Rest muss man durch Analyse rausfinden.
Marius schrieb:> P.S. die unter powerupwait: aufgeführten Zeilen sind noch nicht an das> KS0066 angepasst.
Ja dann mache das erstmal und poste hier das Ergebnis, wenn es dann
immer noch nicht geht.
Thomas
Marius schrieb:> Ok das ist doch mal eine Aussage.>> Was passiert wenn meine Wartezeit höher ist, als im Datenblatt> drinsteht?
Nichts schlimmes.
Länger kannn man (fast) immer warten. Nur kürzer nicht. Der Controller
auf dem LCD benötigt eine gewisse Zeit um eine Aktion zu machen. Die
musst du ihm mindestens geben. Aber er wird nicht ungeduldig wenn du dir
zu lange Zeit lässt.
Äh ich weiß ja nicht ob es wichtig ist, aber ich habe nur 4
Datenleitungen angeschlossen.Allerdings weiß der Controller im LCD ja am
Anfang noch nicht, das er im 4-Bit Modus ist....
Marius schrieb:> Äh ich weiß ja nicht ob es wichtig ist, aber ich habe nur 4> Datenleitungen angeschlossen.Allerdings weiß der Controller im LCD ja am> Anfang noch nicht, das er im 4-Bit Modus ist....
Das macht nichts.
Die Initsequenz und die Codes sind so gestaltet, dass das LCD auch mit
nur 4 Bit korrekt initialisiert werden kann.
Wäre wohl ein bischen witzlos einen 4-Bit Modus zu machen, wenn man dann
trotzdem 8 Datenleitungen braucht. Da könnte man dann auch gleich nur
8-Bit Übertragung machen und sich den Aufwand sparen, ein Byte auf 2 mal
über einen 8-Bit Bus zu übertragen.
Nun gut aber laut Anschlussplan werden DB0 bis DB3 am LCD nicht
angeschlossen.
Laut Plan habe ich es so angschlossen.
DB4 -> PD0 uC
DB5 -> PD1 uC
DB6 -> PD2 uC
DB7 -> PD3 uC
RS -> PD4 uC
E -> PD5 uC
Aber die Initalisierung findet nur DB0 bis DB3 am LCD statt.
oder nicht?
Marius schrieb:> Nun gut aber laut Anschlussplan werden DB0 bis DB3 am LCD nicht> angeschlossen.> Laut Plan habe ich es so angschlossen.> DB4 -> PD0 uC> DB5 -> PD1 uC> DB6 -> PD2 uC> DB7 -> PD3 uC> RS -> PD4 uC> E -> PD5 uC>> Aber die Initalisierung findet nur DB0 bis DB3 am LCD statt.
Nein.
Wie kann DB0 bis DB3 des LCD in die Initialisierung mit eingeschlossen
sein, wenn sie gar nicht angeschlossen sind?
ldi temp1, 0b00000011 ; muss 3mal hintereinander
gesendet
out LCD_PORT, temp1 ; werden zur Initialisierung
Hier wird der Port direkt angesprochen.
Durch die Verkabelung landen die beiden 1 Bits am LCD an den LCD-Pins
DB4 und DB5
ldi temp1, 0b00000010 ; 4bit-Modus einstellen
out LCD_PORT, temp1
Hier dasselbe nocheinmal. Das 1 Bit landet am LCD an DB5
Die restlichen LCD-Pins DB4, DB6, DB7 sind 0. Die nicht angeschlossenen
LCD-Pins DB0 bis DB3 sind ebenfalls 0.
Und jetzt schau nach, was das für das LCD heisst.
Beim HD74.. bedeutet das: 4-Bit Modus
Danach läuft das LCD sicher im 4-Bit Modus und nach diesem Punkt in der
Initialisierung können die Funktionen lcd_data bzw. lcd_command benutzt
werden.
Nur bei den ersten beiden Schritten, dem senden von 0x30 bzw. 0x20 ist
man darauf angewiesen, dass die Pins DB0 bis DB3 dadurch dass sie am LCD
offen gelassen werden, von sich aus 0-Zustand haben wenn das LCD noch im
8-Bit Modus läuft. Bzw. dass sie vom LCD ignoriert werden, weil die
1-Bits ein Kommando spezifizieren, bei dem diese Bits keine Rolle
spielen.
> Aber die Initalisierung findet nur DB0 bis DB3 am LCD statt.> oder nicht?
Oder nicht.
Die Initialisierung in lcd_init setzt Bits in PD0 bis PD3 und die
gelangen auf DB4 bis DB7 am LCD. Und genau in DB4 bis DB7 müssen lt.
Datenblatt die Bits gesetzt sein, die die Initialisierung auslösen.
Also ich habe heute per zufall mal einen kurzen teil meines Testtextes
bekommen.
Stand in Zeile 1 & 3.
Nach einem neuen übertragen war er wieder weg.
Also LCD schein in Ordnung zu sein.
Kann es evtl an einer falschen Fusebiteinstellung liegen?
Ich hab nix an denen verändert.
Es wird auch wie gewünscht der interne Takt verwendet.
Ich hab es nicht so ganz verstanden.
Ich habe jetzt auch nochmal eine andere Routine getest doch wieder geht
sie nicht.
Also entweder verarscht mich der Atmega32 oder das LCD
Marius schrieb:> Ich hab es nicht so ganz verstanden.
?
Was gibt es daran nicht zu verstehen?
Für dich ist das Bild mit dem 4-Bit Modus interessant
Da steht:
Nach dem Anlegen der Spannung mindestens 30 Millisekunden warten ehe man
das LCD anspricht
Danach die Sequenz
D7 D6 D5 D4 RS RW
0 0 1 0 0 0
an die Datenleitungen anlegen, den obligatorischen Enable Puls
nachschieben. Dann nochmal dasselbe (wieder mit einem Enable)
und danach kann man die Bits N und F einstellen. N wird an die LCD
Leitung DB7 ausgegeben, F an die Leitung DB6. DB5 bzw DB4 spielen keine
Rolle und können stehen wie sie wollen.
N und F werden irgendwelche Einstellbits sein, deren Bedeutung an
anderer Stelle im Datenblatt steht.
Wieder ein Enable hinten nach.
Dann noch mindestens 39µs warten und danach ist das LCD auf 4 Bit Modus
konfiguriert und die Konfiguration kann dann über die ganz normale 4-Bit
Übertragungsmethode abgewickelt werden (also jeweils durch Übertragen
von 2 Bytes)
Dann stimmt aber die Routine aus dem Tutorial nicht oder?
lcd_init:
push temp1
in temp1, LCD_DDR
ori temp1, (1<<PIN_E) | (1<<PIN_RS) | 0x0F
out LCD_DDR, temp1
ldi temp3,50
powerupwait:
rcall delay5ms
dec temp3
brne powerupwait
ldi temp1, 0b00100000 ;von mir geändert
out LCD_PORT, temp1
rcall lcd_enable
;rcall delay5ms
ldi temp1, 0b00100000 ;von mir geändert
rcall lcd_enable
;rcall delay5ms
ldi temp1, 0b1100000 ;von mir geändert
rcall lcd_enable
;rcall delay5ms
So wenn ich dann aber im Datenblatt weiter oben gucke sehe ich sowas
Function Set 0 0 0 0 1 DL N F - -
Set interface data length (DL:
8-bit/4-bit), numbers of display line
(N: 2-line/1-line) and, display
font type (F:5´11dots/5´8 dots)
39 ms
So und jetzt soll ein Anfänger da durchsteigen? ;-)
DL bedeutet ja 4 oder 8 Bit Modus
Marius schrieb:> Dann stimmt aber die Routine aus dem Tutorial nicht oder?> ldi temp1, 0b00100000 ;von mir geändert> out LCD_PORT, temp1
und jetzt gehst du einmal her, nimmst die Belegung deines Ports zur Hand
und siehst nach, welche /LCD/-Pins du dadurch auf 0 oder 1 setzt.
Gefordert ist, dass am LCD(!) die Datenpins laut Datenblatt eingestellt
werden. Der Datenblattschreiber kann doch nicht wissen, wie du die Kabel
vom LCD zu deinem µC ziehst! Die können doch auch wild durcheinander
gewürfelt sein, weil es dir zb besser in eine Steckerbelegung passt oder
du dadurch auf einer Leiterbahn keine Bahnüberkreuzungen mehr hast.
Wenn du dir die Belegung nicht merken kannst, dann mach dir einen
Kommentar direkt vor die Funktion
was musst du also am Port ausgeben, damit am LCD(!) DB5 auf 1 ist?
1
;rcall delay5ms
Es schadet nicht, wenn du dem LCD zwischen den Initialisierbytes ein
wenig Zeit lässt auch wenn im Datenblatt nichts dazu steht. Länger darfs
dauern, nur kürzer nicht.
Marius schrieb:> So und jetzt soll ein Anfänger da durchsteigen? ;-)
Ein ANfänger kauft sich aber auch nicht einfach wild irgendetwas ein,
sondern er sieht zuerst nach, ob er Software fertig hat, für die
Hardware die er sich kaufen will. Und im Zweifelsfall kauft er sich die
Hardware, für die er auch Ansteuerprogramme hat. Eben weil er Anfänger
ist, und das noch nicht kann.
Hi
>So wenn ich dann aber im Datenblatt weiter oben gucke sehe ich sowas>Function Set 0 0 0 0 1 DL N F - -
....
>So und jetzt soll ein Anfänger da durchsteigen? ;-)
Die Befehle sind auch noch mal einzeln erläutert (unter INSTRUCTION
DESCRIPTION). Da steht auch die Bedeutung der einzelnen Bits.
MfG Spess
Hallo Marius,
frueher, als ich noch klein war, es noch kein Mikrocontroller.net gabe,
das Fernsehen aber schon farbig war, habe ich dieses Problem alleine
geloest:
Schaltung an den Emulator gehaengt und dann jeweils einen uC-Befehl nach
den anderen abgearbeitet.
Dann ein Multimeter genommen, an die Pins gehalten und geschaut, ob dort
das liegt, was ich erwartete.
Geht das heute nicht mehr?
Du hast ja jetzt erfahren (obwohl das schon prima im Datenblatt steht),
dass es dem LCD garnicht lngsam genug gehen darf......
Aus meiner Erfahrung liegen 95% der Fehler daran, dass ein Portpin
falsch deklariert ist....besonders bei den PIC.
Vom Rest der Fehler sind wieder 95% darauf zurueckzufuehren, dass das
Timing nicht nach Datenblatt war.
Der Rest sind dann SW Fehler, aber das passiert ja heute kaum noch, weil
jeder Software von jemand anderem abkupfert (oder sich aus
mikrocontroller.net holt).
Gruss und viel Erfolg
Michael
Hallo Karl-Heinz
> Ein ANfänger kauft sich aber auch nicht einfach wild irgendetwas ein,> sondern er sieht zuerst nach, ob er Software fertig hat, für die> Hardware die er sich kaufen will. Und im Zweifelsfall kauft er sich die> Hardware, für die er auch Ansteuerprogramme hat. Eben weil er Anfänger> ist, und das noch nicht kann.
Das passiert hier aber immer haeufiger.
Ist ja prima, dass es so viele Jungs und MAedel gibt, die technisch und
auch am Basteln noch interessiert sind, und wir haben ja auch mal klein
angefangen.
Aber hier geht es nach dem Motto:
F: "ich hab mir jedst pinsel gekaufd und will ein bild wie rembrandt
mahlen wie mache ich dass"
A: "Na, hoffentlich hast Du auch die entsprechenden Farben und eine
Leinwand besorgt"
F: "nee statt leinwand nehme ich druckerpapier und das muss auch ohne
farben gehen. kann mir jemant sagen, was ich machen muss?
..
F: " wasn los... kann mir immernochkeiner helfen?
Gruss
Michael
@ Karl Heinz:
> brne powerupwait> ldi temp1, 0b00100000 ;von mir geändert
Meintest du nicht:
ldi temp1, 0b00000010 ;Low-Nibble sind die Datenleitungen
Thomas
Michael Roek-ramirez schrieb:> Das passiert hier aber immer haeufiger.
Ich weiß.
Das liegt IMHO an der Vorstellung, dass Computer bauen so aussieht:
* in den Mediamarkt gehen
* irgendeine Karte kaufen
* PC aufschrauben
* Karte einstecken
* CD einlegen
* fertig
Mit viel Glück kann man die Leute noch dazu bringen, dass sie vor dem
Einstecken der Karte den Rechner stromlos schalten. Das sind dann die,
die über Vorwissen verfügen.
Thomas Forster schrieb:> @ Karl Heinz:>>> brne powerupwait>> ldi temp1, 0b00100000 ;von mir geändert>
Ich hab nur seinen Code zitiert.
> Meintest du nicht:>> ldi temp1, 0b00000010 ;Low-Nibble sind die Datenleitungen
Meinte ich.
Aber eigentlich sollte Marius das selber rausfinden :-(
Denn dann haette er es verstanden. Jetzt malt er wieder nur anderen Code
ab und versteht nicht, wie es dazu kommt. Na hoffentlich hat er
wenigstens die Erklärung dazu verstanden.
@ Marius
> Dann stimmt aber die Routine aus dem Tutorial nicht oder?
Doch, sie stimmt. Aber sie ist eben nicht für ein KS0066-LCD, sondern
für ein HD44780-LCD. Und diese beiden unterscheiden sich in der
Initialisierung.
Deshalb sollst du ja das Datenblatt des KS0066 runterladen und die dort
beschriebene Intialisierung in dene einpassen.
Bisher:
powerupwait:
rcall delay5ms
dec temp3
brne powerupwait
ldi temp1, 0b00000011 ; muss 3mal hintereinander
gesendet
out LCD_PORT, temp1 ; werden zur Initialisierung
rcall lcd_enable ; 1
rcall delay5ms
rcall lcd_enable ; 2
rcall delay5ms
rcall lcd_enable ; und 3!
rcall delay5ms
Auf dem Bild von Stefan
http://www.mikrocontroller.net/attachment/89023/4-bit.gif
steht für 4-Bit-Modus: DB7-DB4: 0010
Weiterhin wird das nur 2 mal gesendet:
powerupwait:
rcall delay5ms
dec temp3
brne powerupwait
ldi temp1, 0b00000010 ; muss 2mal hintereinander
gesendet
out LCD_PORT, temp1 ; werden zur Initialisierung
rcall lcd_enable ; 1
rcall delay5ms
rcall lcd_enable ; 2
rcall delay5ms
Dritte Zeile im 1. Block: N und F
Beide sollen 1 sein, Rest egal. Also DB7-DB4: 1100
Deine Befehlszeilen lauten dann:
ldi temp1, 0b00001100
rcall lcd_enable
rcall delay5ms
Jetzt kommt der nächste Block: Display ON/OFF
Die beiden Zeilen bedeuten, dass der eigentliche 8-Bit-Befehl mi Bild
bereits in zwei 4-bit-Befehle zerlegt ist, welche hintereinander zu
senden sind. das Display weiß zu diesem Zeitpunkt ja schon, dass es im
4-Bit-Modus arbeiten soll und setzt die beiden Botschaften für sich
wieder zu einer zusammen.
Ich beschäftige mich seit etwa 3 Wochen mit dem Thema LCD.
Mir läuft die Zeit weg.
Das Thema ist kein Hobby von mir.
Ich bitte deswegen meine Fragen, die für euch Profis als eher lächerlich
bezeichnet werden, zu entschuldigen.
Wieso sagen andere Foren, das KS0066 und HD44780 sich nicht
unterscheiden???
Woher soll ich wissen, was richtig ist?
Ich habe halt das andere nicht.
Ich wusste nicht das es unterschiede gibt, als ich das Display bestellt
hatte.
Ich mache mein Techniker Projekt und ich habe den Aufwand der Software
oder vielmehr Wissensstand den man für die Software brauch,
unterschätzt.
Also ich danke euch bis hier schon mal.
Gruß
Marius
> Mir läuft die Zeit weg.
Okay, Das ist schlecht. Mehr siehe unten.
> Das Thema ist kein Hobby von mir.
Ich mache das tatsächlich aus Hobby. Auch so kann man das lernen.
> Ich bitte deswegen meine Fragen, die für euch Profis als eher lächerlich> bezeichnet werden, zu entschuldigen.
Grundsätzlich sind deine Fragen nicht lächerlich. Uns erschien
allerdings, dass du die Antworten und Tipps nur oberflächlich übernommen
hast.
> Woher soll ich wissen, was richtig ist?
Auch Menschen in Foren können irren. Am wenigsten irren sich die
Datenblätter. Also immer als erstes Datenblatt vom Hersteller besorgen
und aufmerksam lesen.
> Ich mache mein Techniker Projekt und ich habe ...
Viel Erfolg.
Da du ja dann bald als Techniker arbeitest: Die Abschätzung des
Aufwandes für ein neues Projekt ist zwar immer schwierig, aber bereits
hier wird zum Teil entschieden, ob das Projekt ins Ziel kommen kann oder
nicht.
Eine gute Vorrausplanung und Abschätzung über den Realisierungsaufwand
für ein Projekt ist immens wichtig. Hier sollte man in Ruhe herangehen.
So sollte das im Arbeitsleben dann auch laufen. (Sollte..)
Wenn jetzt die Zeit zu rennen beginnt: Mache einen Terminplan, was noch
zu erledigen ist und wieviel Zeit die einzelnen Abschnitte noch
benötigen....
Hallo Marius,
ich habe den Thread überflogen, konnte aber auf die Schnelle nirgendwo
eine Angabe dazu finden, um welches Display es sich genau handelt.
"Erste und dritte Zeile voll ausgefüllt" heißt bei den mir bekannten
Displays meistens, dass die Kontrastspannung nicht stimmt. Das solltest
du als erstes überprüfen.
Ich arbeite gerne nach der Devise: teile und (be-)herrsche:
1.
Bau Dir ne Nibble-Funktion, die ein Nibble ausgibt, ohne die anderen 3
Pins zu ändern.
2.
Bau Dir daraus ne Byte-Funktion
3.
Bau Dir daraus nen Datenfunktion
und noch ne Kommandofunktion.
Beachte, einige Kommandos brauchen länger (~2ms Delay reicht).
4.
Baue Dir aus Nibble- und Kommandofunktion das Init.
D.h. außer die 6 Pins als Ausgang zu setzen, fäßt das Init die Pins
nicht mehr direkt an!
Fertig.
In Assembler solltest Du Dir auch zuerst eine Aufrufkonvention
ausdenken, d.h. welche Register für Paramterübergabe und welche als
Scratchpad reserviert sind. Die kann dann jede Funktion benutzen und
zerstören ohne Unmengen an lästigem Push/Pop.
Benötigt der Aufrufer diese Register später noch, muß er sie eben selber
sichern.
Die Aufrufkonvention hilft Dir auch, den Überblick zu behalten.
Peter
Marius schrieb:> Hier steht was dazu.>> Aber es sieht alles ok aus.>> Aber es schein nicht ok zu sein, sonst würde es ja funzen ;-)
Zuerst mal solltest du deine Tests festlegen
Der wichtigste Test ist:
Strom aus
Strom an
Wird das LCD da richtig initialisiert?
Hier greift die 4-Bit Sequenz aus dem Datenblatt.
Wir wissen:
Der Controller am LCD initialisiert sich selber im 8 Bit Modus
d.h. von der ersten Übertragung
D7 D6 D5 D4 D3 D2 D1 D0
0 0 1 0 x x x x
wertet das LCD effetkiv nur D4 aus. Dies deshalb weil D5 1 ist und das
das Kommando zur Festlegung von DL, N und F wäre. Du kannst hier aber
nur DL (D4) einstellen. N und F können so (noch) nicht eingestellt
werden, weil der µC keine Kontrolle über D3 und D2 hat (keine Leitungen
dorthin)
Aber die 0 in D4 sagt dem LCD-Controllen bei diesem Kommando, dass er
auf 4 Bit Bus umschalten soll.
Das tut er auch (hoffentlich)
Damit ist der Controller jetzt auf 4-Bit Modus und dasselbe Kommando
kann noch einmal abgesetzt werden, diesmal allerdings schon über den
normalen 4-Bit Mechanismus, also auf 2 mal: zuerst High-Nibble, dann
Low-Nibble.
Also wird noch einmal
0 0 1 0
an die Datenpins ausgegeben. Da der Controller schon im 4-Bit Modus ist,
wartet er noch auf das Low-Nibble, welches ihm sogleich vorgesetzt wird
N F 0 0
(für N und F die richtigen Werte 0 oder 1 einsetzen)
In Summe wird hier einfach das Konfigurationsbyte 2 mal übertragen. Das
erste mal mit dem Controller im 8-Bit Modus, wobei der Controller danach
auf 4 Bit Modus umschaltet und der µC keine Kontrolle über N und F hat.
Und erst das 2.te mal kann dann auch N und F programmiert werden.
Soweit so gut.
Der Test müsste auf jeden Fall funktionieren. Nach einem Power-On Reset
müsste das LCD damit initialisiert werden können.
Der interessante Fall ist jetzt aber Fall 2.
Genannte Sequenz geht nämlich schief, wenn sich der Controller bereits
(aus einer vorhergehenden Initialisierung) im 4-Bit Modus befindet.
Und jetzt beginnt die Fitzelarbeit, eine Sequenz zu finden, die
unabhängig davon ob der Controller im 8 oder 4 Bit Modus ist, auf jeden
Fall den 4 Bit Modus aktiviert. Hinweis: Der Weg führt IMHO darüber den
Controller erst mal gezielt in den 8 Bit Modus zu schalten.
Dazu muss
0 0 1 1 N F 0 0
ausgegeben werden.
Jetzt wissen wir aber an dieser Stelle nicht, ob der Controller im 8 Bit
oder im 4 Bit Modus ist. Ist er im 4 Bit Modus, so wartet er noch auf
ein 2.tes Nibble (für N und F).
Wenn wir also am Port ausgeben
D7 D6 D5 D4
0 0 1 1
0 0 1 1
und der Controller ist im 8 Bit Modus,
dann wertet er das als 2 Konfigurationsanweisungen, die ihn 2 mal in den
8 Bit Modus setzen würden (für N und F saugt er sich jeweils etwas aus
den Fingern)
Ist der Controller aber im 4 Bit Modus, so interpretiert der Controller
die Ausgabe von
0 0 1 1
0 0 1 1
als 1 Konfigurationsanweisung, mit der er in den 8 Bit MOdus schaltet
und er ein N und ein F von jeweils 0 setzen soll
Aber auf N und F kommt es hier nicht an. Wichtig ist, dass der
Controller nach diesen beiden Ausgaben auf jeden Fall im 8 Bit Modus
ist, egal in welchem Modus er vorher war.
Eine Initialiserungssequenz, die also auf jeden Fall funktioniert,
lautet
0 0 1 1
0 0 1 1
0 0 1 0
Danach ist der Controller im 4 Bit Modus und die Konfiguration
(beginnend mit DL, N und F) kann über ganz normale 2-Nibble Übertragung
fertig gestellt werden
Marius schrieb:> Aber es schein nicht ok zu sein, sonst würde es ja funzen ;-)>> Gruß>> Marius
Die Spezifikation ist vollständig und ausreichend. Was ich gesehen habe
ist die init exakt gleich dem, was auch in der pdf vom TC1602A Display
steht.
Ich schicke dir die komplette Displaysoftware, die einwandfrei mit t2313
läuft. Es ist aber nur ein Teil meines Projektes, das noch lange nicht
fertig ist. Habe die Displayroutine herausgelöst, bis das Display läuft,
was es jetzt macht.
Die SW die im Thread schon genannt ist, hat bei mir auch nicht
funktioniert.
Aber du hast doch von einem vierzeiligen Display gesprochen?
LG Rudi
Dann rechne doch die Delayzeiten nach.
Siehe meine display.asm mit 8 Mhz Takt
Mein Display braucht 38 us und 1,52 ms
in der init 4,1 ms
Ich hab die delays mit Reserve ausgelegt.
Gratulation dass es auch schon bei dir läuft!!
Das wars dann denke ich. Sonst einfach fragen.
LG Rudi
Marius schrieb:> Ich habe den internen Takt auf 2MHz gesetzt und im Programm gesagt das> xtal 4MHz ist.
Und im Programm steht aber:
1
.equ XTAL = 8000000
Wie wärs, wenn Du Dich mal entscheiden könntest?
Wenn Deine Delays nie stimmen, brauchst Du Dich nicht zu wundern.
Schreib Dir erstmal ein Delay-Macro, was aus F_CPU einigermaßen
stimmende Delays erzeugt.
Peter