ProgDom
31.03.2005, 13:36
Hallo,
ich hab jetzt mal wieder so ein typisches Problem von einem Anfänger, bei dem man nicht einmal weiß, woran es denn liegt.
Ich würde mich sehr freuen, wenn mir einige von euch helfen könnten.
Ich habe ein LCD und habe noch nie ein solches mit meinem Atmega8 angesteuert. Ich habe jetzt ersteinmal folgende Verbindungen vorgenommen:
1 -> Vss -> GND
2 -> Vdd-> +5V
3 -> Vo -> -3V
4 -> RS -> PC4 am AVR
5 -> RW -> GND
6 -> E -> PC5 am AVR
7 -> DB0-> GND
8 -> DB1-> GND
9 -> DB2-> GND
10-> DB3-> GND
11-> DB4-> PC0 am AVR
12-> DB5-> PC1 am AVR
13-> DB6-> PC2 am AVR
14-> DB7-> PC3 am AVR
Wie man vermutlich schon erkennen kann, möchte ich das LCD im 4-Bit Modus ansprechen.
Wenn ich den Strom am Display anschalte sehe ich auch schwarze Balken, wie es üblich ist und auch soll. Ich kann das Display jedoch nicht ansprechen. Zurzeit verwende ich folgenden Assembler-Code von www.mikrocontroller.net:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LCD-Routinen ;;
;; ============ ;;
;; (c)andreas-s@web.de ;;
;; ;;
;; 4bit-Interface ;;
;; DB4-DB7: PC0-PC3 ;;
;; RS: PC4 ;;
;; E: PC5 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;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
out PORTC, 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 PORTC, 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 ohne RS zu setzen
mov temp2, temp1
swap temp1
andi temp1, 0b00001111
out PORTC, temp1
rcall lcd_enable
andi temp2, 0b00001111
out PORTC, temp2
rcall lcd_enable
rcall delay50us
ret
;erzeugt den Enable-Puls
lcd_enable:
sbi PORTC, 5 ;Enable high
nop ;3 Taktzyklen warten
nop
nop
cbi PORTC, 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 PORTC, 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 PORTC, temp1
rcall lcd_enable
rcall delay5ms
ldi temp1, 0b00101000 ;noch was einstellen...
rcall lcd_command
ldi temp1, 0b00001100 ;...nochwas...
rcall lcd_command
ldi temp1, 0b00000100 ;endlich fertig
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
und
.include "m8def.inc"
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18
ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp1
ldi temp1, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp1
ldi temp1, 0xFF ;Port D = Ausgang
out DDRC, temp1
rcall lcd_init ;Display initialisieren
rcall lcd_clear ;Display löschen
ldi temp1, 'A' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'B' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'C' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'D' ;Zeichen anzeigen
rcall lcd_data
loop:
rjmp loop
.include "lcd-routines.asm" ;LCD-Routinen werden hier eingefügt
Leider hat das nichts am LCD verändert. Es sind immernoch nur die Balken zu sehen.
Ich weiß nicht, ob es an dem Code oder an der Hardware liegt, da mein LCD etwas anders ist. Aus diesem Grund habe ich einmal Datenblatt und Ansteuerhinweis unten angefügt !
Ich hoffe, dass mir jemand bei meinem Problem helfen kann, da ich gerne mal "normale" Zeichen auf meinem LC-Display sehen möchte.
**********************
MFG
ProgDom
ich hab jetzt mal wieder so ein typisches Problem von einem Anfänger, bei dem man nicht einmal weiß, woran es denn liegt.
Ich würde mich sehr freuen, wenn mir einige von euch helfen könnten.
Ich habe ein LCD und habe noch nie ein solches mit meinem Atmega8 angesteuert. Ich habe jetzt ersteinmal folgende Verbindungen vorgenommen:
1 -> Vss -> GND
2 -> Vdd-> +5V
3 -> Vo -> -3V
4 -> RS -> PC4 am AVR
5 -> RW -> GND
6 -> E -> PC5 am AVR
7 -> DB0-> GND
8 -> DB1-> GND
9 -> DB2-> GND
10-> DB3-> GND
11-> DB4-> PC0 am AVR
12-> DB5-> PC1 am AVR
13-> DB6-> PC2 am AVR
14-> DB7-> PC3 am AVR
Wie man vermutlich schon erkennen kann, möchte ich das LCD im 4-Bit Modus ansprechen.
Wenn ich den Strom am Display anschalte sehe ich auch schwarze Balken, wie es üblich ist und auch soll. Ich kann das Display jedoch nicht ansprechen. Zurzeit verwende ich folgenden Assembler-Code von www.mikrocontroller.net:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LCD-Routinen ;;
;; ============ ;;
;; (c)andreas-s@web.de ;;
;; ;;
;; 4bit-Interface ;;
;; DB4-DB7: PC0-PC3 ;;
;; RS: PC4 ;;
;; E: PC5 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;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
out PORTC, 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 PORTC, 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 ohne RS zu setzen
mov temp2, temp1
swap temp1
andi temp1, 0b00001111
out PORTC, temp1
rcall lcd_enable
andi temp2, 0b00001111
out PORTC, temp2
rcall lcd_enable
rcall delay50us
ret
;erzeugt den Enable-Puls
lcd_enable:
sbi PORTC, 5 ;Enable high
nop ;3 Taktzyklen warten
nop
nop
cbi PORTC, 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 PORTC, 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 PORTC, temp1
rcall lcd_enable
rcall delay5ms
ldi temp1, 0b00101000 ;noch was einstellen...
rcall lcd_command
ldi temp1, 0b00001100 ;...nochwas...
rcall lcd_command
ldi temp1, 0b00000100 ;endlich fertig
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
und
.include "m8def.inc"
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18
ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp1
ldi temp1, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp1
ldi temp1, 0xFF ;Port D = Ausgang
out DDRC, temp1
rcall lcd_init ;Display initialisieren
rcall lcd_clear ;Display löschen
ldi temp1, 'A' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'B' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'C' ;Zeichen anzeigen
rcall lcd_data
ldi temp1, 'D' ;Zeichen anzeigen
rcall lcd_data
loop:
rjmp loop
.include "lcd-routines.asm" ;LCD-Routinen werden hier eingefügt
Leider hat das nichts am LCD verändert. Es sind immernoch nur die Balken zu sehen.
Ich weiß nicht, ob es an dem Code oder an der Hardware liegt, da mein LCD etwas anders ist. Aus diesem Grund habe ich einmal Datenblatt und Ansteuerhinweis unten angefügt !
Ich hoffe, dass mir jemand bei meinem Problem helfen kann, da ich gerne mal "normale" Zeichen auf meinem LC-Display sehen möchte.
**********************
MFG
ProgDom