Forum: Mikrocontroller und Digitale Elektronik LCD Routine Funktioniert nicht


von Marius (Gast)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Marius (Gast)


Lesenswert?

ich habe ihn mit dem Standart Takt von 1MHz getaktet.

von Marius (Gast)


Lesenswert?

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.

von Marius (Gast)


Lesenswert?

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

von Thomas F. (igel)


Lesenswert?

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

von Marius (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Im Datenblatt vom KS0066 steht die Initialisierung für 4Bit-Mode drin.
einfach nachsehen und vergleichen.

MfG Spess

von Marius (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Thomas P. (topla)


Lesenswert?

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

von Marius (Gast)


Lesenswert?

Ok das ist doch mal eine Aussage.

Was passiert wenn meine Wartezeit höher ist, als im Datenblatt 
drinsteht?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Thomas P. (topla)


Lesenswert?

Nix, es steht da "wait for more than...", nur zu kurz ist kritisch.

Thomas

von Marius (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Marius (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

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

von Marius (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

Marius schrieb:

> Ich hab nix an denen verändert.
>
> Es wird auch wie gewünscht der interne Takt verwendet.

Mach mal alle delays länger.

von Thomas F. (igel)


Lesenswert?

Hast du die LCD-Routine inzwischen an deinen KS066 und 4-Bit Modus 
angepasst, wie es das Bild von Stefan oben beschreibt?

von Marius (Gast)


Lesenswert?

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

von Marius (Gast)


Angehängte Dateien:

Lesenswert?

Das ist die Routine die ich im Moment benutze.

von Karl H. (kbuchegg)


Lesenswert?

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)

von Marius (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
1
;******************************************************
2
; Pinbelegung am Port -> LCD
3
;
4
; Portbit     7   6   5   4   3   2   1   0
5
;
6
; am LCD      X   X   E  RS  DB7 DB6 DB5 DB4
7
;
8
;******************************************************
9
10
lcd_init:
11
           push  temp1
12
           in    temp1, LCD_DDR
13
           ori   temp1, (1<<PIN_E) | (1<<PIN_RS) | 0x0F
14
           out   LCD_DDR, temp1
15
16
           ldi   temp3,50
17
powerupwait:
18
           rcall delay5ms
19
           dec   temp3
20
           brne  powerupwait
21
           ldi   temp1,    0b00100000   ;von mir geändert

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Michael R. (mexman) Benutzerseite


Lesenswert?

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

von Michael R. (mexman) Benutzerseite


Lesenswert?

Ach.....und manchmal geht tatsaechlich ein an den LCD-Pin geloetetest 
Kabel ab oder man verwechselt RS und RW beim Anschliessen ;-)

von Michael R. (mexman) Benutzerseite


Lesenswert?

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

von Thomas F. (igel)


Lesenswert?

@ Karl Heinz:

>   brne  powerupwait
>   ldi   temp1,    0b00100000   ;von mir geändert

Meintest du nicht:

   ldi temp1, 0b00000010   ;Low-Nibble sind die Datenleitungen


Thomas

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Thomas F. (igel)


Lesenswert?

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

von Stefan W. (wswbln)


Lesenswert?

...und wieder einmal muss ich die Engelsgeduld von Karl Heinz bewundern!

von Marius (Gast)


Lesenswert?

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

von Thomas F. (igel)


Lesenswert?

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

von Marius (Gast)


Lesenswert?

So ich hab das mal alles Ausprobiert. Aber das LCD sagt nö ;-)

Hm vielleicht ist es ja doch kaputt?!

von Detlev T. (detlevt)


Lesenswert?

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.

von Marius (Gast)


Lesenswert?

4x20
http://de.farnell.com/batron/bthq42005vss-smn-led-white/lcd-modul-a-n-20x4/dp/9448888?Ntt=9448888


Bei mir ist der Balken nur noch ganz schwach zu sehen.

Denke das sind noch +2,5V





Der Haken bei Jtagen ist bei mir enable.

Aber schon von anfang an.

Ist das ein Problem?

Im Datenblatt des Atmega32 stehen bei den Ausgängen irgendwelche Werte 
in Klammern


Gruß

Marius

von Rudi D. (rulixa)


Lesenswert?

Das Problem kenne ich gut, habe es beim TC1602A gerade gelöst.
Selbst dann suchte ich noch 3 Tage nach einem Fehler, der in den 
Ausführungszeiten eines Befehls begründet war.

Mir ist es erst gelungen als ich eine Spec meines Displays gefunden 
hatte.
Beitrag "LCD TC1602 Initialisierung"
Beitrag "kurze Frage zu TC1602A Initialisierung via t2313"

Ich habe nicht die Befehle_Spec. incl. der Ausführungszeiten von deinem 
Display/Controller gefunden.
Hast du die schon?

http://www.eio.com/p-939-orient-display-amc2004a-b-b6wtdw-4x20-character-lcd-display-module.aspx
Da ist was ähnliches vielleicht. Die Init ist genau beschrieben.
Lass mich wissen, wenn du so was für den KS0066 Controller gefunden 
hast.

LG Rudi

von Marius (Gast)


Angehängte Dateien:

Lesenswert?

Hier steht was dazu.

Aber es sieht alles ok aus.

Aber es schein nicht ok zu sein, sonst würde es ja funzen ;-)

Gruß

Marius

von Peter D. (peda)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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

von Rudi D. (rulixa)


Angehängte Dateien:

Lesenswert?

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

von Marius (Gast)


Lesenswert?

Hm es läuft.

Ich habe den internen Takt auf 2MHz gesetzt und im Programm gesagt das 
xtal 4MHz ist.

kratzkratzkratz

von Rudi D. (rulixa)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

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.