teslanikola
10.05.2006, 22:38
Hallo leute ich bin dabei ein Prog zu schreiben welches mir daten auf einem LCD ausgibt, nun hab ich erst mal die Byte in ein 3-Stellen ASCII geprogt, die letzte ziffer ( Einer ) passt acuh immer wunderbar nur bei den beiden ersten ( Hunderter und Zehner ) bekomme ich auf dem LCD nur nonsens, aber der hammer ist lauf simulation stimmt der erzeugfte ASCII. Ich kannn den Feheler nicht finden. Was mache ich falsch??
Hier mal der Code:
;################################################# ##################################
;# #
;# LCD Testprogramm #
;# ------------------- #
;# #
;# Microcontroller: ATMEGA8 #
;# Quarz: 4.194304 MHz #
;# #
;# Autor: Denis Bethäuser #
;# www.elektronik4freaks.de.tk #
;# denis.bethaeuser@gmx.de #
;# #
;################################################# ##################################
;----[ µC Includefile ]-------------------------------------------------------------
.include "m8def.inc"
;----[ Register Def. / Alias Def. ]-------------------------------------------------
.def tmp = r16
.def tmp2 = r17
.def tmp3 = r18
.def BCDH = r19 ;Hunderter Ziffer
.def BCDZ = r20 ;Zehner Ziffer
.def BCDE = r21 ;Einer Ziffer
.equ db0 = 0
.equ db1 = 1
.equ db2 = 2
.equ db3 = 3
.equ db4 = 4
.equ db5 = 5
.equ db6 = 6
.equ db7 = 7
.equ rs = 4
.equ en = 5
.equ lcd_port = portc
;----[ STACK-Pointer un Z-Pointer Einrichten ]---------------------------------------
ldi tmp, high(ramend) ;High-Byte in Stackpointer schreiben
out sph, tmp
ldi tmp, low(ramend) ;Low-Byte in Stackpointer schreiben
out spl, tmp
;----[ I/O Einstellungen ]----------------------------------------------------------
ser tmp ;Der gesammte Portc als Ausgang
out ddrc, tmp
;---[ LCD Initialisieren ]----------------------------------------------------------
rcall lcdinit ;Display initialisieren
rcall lcd_cls ;Display löschen
;---[ Hauptprogramm ]---------------------------------------------------------------
main:
ldi tmp, 234
BCDH:
cpi tmp, 100
brcs BCDZ
subi tmp, 100
inc BCDH
rjmp BCDH
BCDZ:
cpi tmp, 10
brcs BCDE
subi tmp, 10
inc BCDZ
rjmp BCDZ
BCDE:
mov BCDE, tmp
subi BCDH, -'0'
subi BCDZ, -'0'
subi BCDE, -'0'
rcall lcd_cls
mov tmp, BCDH
rcall lcd_out
mov tmp, BCDZ
rcall lcd_out
mov tmp, BCDE
rcall lcd_out
end: rjmp end
; LCD - Sende / Empfang - Subroutinen
; =======================================
;###[ lcd_init Initialisierung ]################################################## #
lcdinit:
ldi tmp3 , 10
poweron: ;Wartet 10x 5ms nach dem Einschalten von Vcc
rcall waitms5
dec tmp3
brne poweron
ldi tmp, (1<<db0)|(1<<db1) ;Datenleitung 4 und 5 setzen und 3mal senden
out lcd_port, tmp ;1mal
rcall toogleen
out lcd_port, tmp ;2mal
rcall toogleen
out lcd_port, tmp ;3mal
rcall toogleen
rcall waitms5 ;und nochmals warten
ldi tmp, (1<<db1) ;4-Bit Modus aktivieren
out lcd_port,tmp
rcall waitms5 ;und schon wieder 5ms warten
ldi tmp, (1<<db5)|(1<<db3) ;5x7-Dots und 2-Lines
rcall lcd_com
ldi tmp, (1<<db3)|(1<<db2) ;Display On, Cursor off, Blinking off
rcall lcd_com
ldi tmp, (1<<db2) ;Entry Mode und FERTIG
rcall lcd_com
rcall lcd_cls ;So jetzt noch den Display löschen und ab gehts
ret
;###[ lcd_out Daten senden ]################################################## #####
lcd_out:
mov tmp2, tmp ;Befehlsbyte kopieren
swap tmp ;Nippeltausch ( Hightbits zuerst senden )
andi tmp, 0b00001111 ;es dürfen ja nur die Pin0 - 4 gesetzt werden
out lcd_port, tmp ;und ab ins LCD damit
sbi lcd_port, rs ;und die RS Leitung setzen
rcall toogleen
cbi lcd_port, rs ;und die RS Leitung rücksetzen
andi tmp2, 0b00001111 ;so und jetzt die 4 Lowbits fürn Port zuschneiden
out lcd_port, tmp2 ;und ab ins LCD
sbi lcd_port, rs ;RS Leitung setzen
rcall toogleen
rcall waitus50 ;und wieder 50µS warten
cbi lcd_port, rs ;RS Leitung rücksetzen
ret
;###[ lcd_com Befehle senden ]################################################## ###
lcd_com:
mov tmp2, tmp ;Befehlsbyte kopieren
swap tmp ;Nippeltausch ( Hightbits zuerst senden )
andi tmp, 0b00001111 ;es dürfen ja nur die Pin0 - 4 gesetzt werden
out lcd_port, tmp ;und ab ins LCD damit
rcall toogleen
andi tmp2, 0b00001111 ;so und jetzt die 4 Lowbits fürn Port zuschneiden
out lcd_port, tmp2 ;und ab ins LCD
rcall toogleen
rcall waitus50 ;und wieder 50µS warten
ret
;###[ lcd_cls Display löschen ]################################################## ##
lcd_cls:
ldi tmp, (1<<db0) ;Display löschen
rcall lcd_com
rcall waitms5
ret
; WARTESCHAUFEN UND SONST. SUBs
; =================================
;---[ Enable Set/Reset ]------------------------------------------------------------
toogleen:
sbi lcd_port,en ;Enable auf High setzen
nop ;1µSec Warten
nop
nop
nop
cbi lcd_port,en ;Enable au Low setzen
ret
;---[ 50µS warten ]-----------------------------------------------------------------
waitus50: ;Genau 50µS warten ( 190 + 10 Clocks bei 4MHz )
ldi tmp, $3F
WGLP3: dec tmp
brne WGLP3
nop
ret
;---[ 5mS warten ]------------------------------------------------------------------
waitms5: ;Ganz genau 5ms warten (19990 + 10 Clocks bei 4MHz)
ldi tmp, $1E
WGLP0: ldi tmp2, $DD
WGLP1: dec tmp2
brne WGLP1
dec tmp
brne WGLP0
ldi tmp, $03
WGLP2: dec tmp
brne WGLP2
nop
ret
Bin daran meine Programmierkünste anzuzweifeln, helft mir bitte!!!
Hier mal der Code:
;################################################# ##################################
;# #
;# LCD Testprogramm #
;# ------------------- #
;# #
;# Microcontroller: ATMEGA8 #
;# Quarz: 4.194304 MHz #
;# #
;# Autor: Denis Bethäuser #
;# www.elektronik4freaks.de.tk #
;# denis.bethaeuser@gmx.de #
;# #
;################################################# ##################################
;----[ µC Includefile ]-------------------------------------------------------------
.include "m8def.inc"
;----[ Register Def. / Alias Def. ]-------------------------------------------------
.def tmp = r16
.def tmp2 = r17
.def tmp3 = r18
.def BCDH = r19 ;Hunderter Ziffer
.def BCDZ = r20 ;Zehner Ziffer
.def BCDE = r21 ;Einer Ziffer
.equ db0 = 0
.equ db1 = 1
.equ db2 = 2
.equ db3 = 3
.equ db4 = 4
.equ db5 = 5
.equ db6 = 6
.equ db7 = 7
.equ rs = 4
.equ en = 5
.equ lcd_port = portc
;----[ STACK-Pointer un Z-Pointer Einrichten ]---------------------------------------
ldi tmp, high(ramend) ;High-Byte in Stackpointer schreiben
out sph, tmp
ldi tmp, low(ramend) ;Low-Byte in Stackpointer schreiben
out spl, tmp
;----[ I/O Einstellungen ]----------------------------------------------------------
ser tmp ;Der gesammte Portc als Ausgang
out ddrc, tmp
;---[ LCD Initialisieren ]----------------------------------------------------------
rcall lcdinit ;Display initialisieren
rcall lcd_cls ;Display löschen
;---[ Hauptprogramm ]---------------------------------------------------------------
main:
ldi tmp, 234
BCDH:
cpi tmp, 100
brcs BCDZ
subi tmp, 100
inc BCDH
rjmp BCDH
BCDZ:
cpi tmp, 10
brcs BCDE
subi tmp, 10
inc BCDZ
rjmp BCDZ
BCDE:
mov BCDE, tmp
subi BCDH, -'0'
subi BCDZ, -'0'
subi BCDE, -'0'
rcall lcd_cls
mov tmp, BCDH
rcall lcd_out
mov tmp, BCDZ
rcall lcd_out
mov tmp, BCDE
rcall lcd_out
end: rjmp end
; LCD - Sende / Empfang - Subroutinen
; =======================================
;###[ lcd_init Initialisierung ]################################################## #
lcdinit:
ldi tmp3 , 10
poweron: ;Wartet 10x 5ms nach dem Einschalten von Vcc
rcall waitms5
dec tmp3
brne poweron
ldi tmp, (1<<db0)|(1<<db1) ;Datenleitung 4 und 5 setzen und 3mal senden
out lcd_port, tmp ;1mal
rcall toogleen
out lcd_port, tmp ;2mal
rcall toogleen
out lcd_port, tmp ;3mal
rcall toogleen
rcall waitms5 ;und nochmals warten
ldi tmp, (1<<db1) ;4-Bit Modus aktivieren
out lcd_port,tmp
rcall waitms5 ;und schon wieder 5ms warten
ldi tmp, (1<<db5)|(1<<db3) ;5x7-Dots und 2-Lines
rcall lcd_com
ldi tmp, (1<<db3)|(1<<db2) ;Display On, Cursor off, Blinking off
rcall lcd_com
ldi tmp, (1<<db2) ;Entry Mode und FERTIG
rcall lcd_com
rcall lcd_cls ;So jetzt noch den Display löschen und ab gehts
ret
;###[ lcd_out Daten senden ]################################################## #####
lcd_out:
mov tmp2, tmp ;Befehlsbyte kopieren
swap tmp ;Nippeltausch ( Hightbits zuerst senden )
andi tmp, 0b00001111 ;es dürfen ja nur die Pin0 - 4 gesetzt werden
out lcd_port, tmp ;und ab ins LCD damit
sbi lcd_port, rs ;und die RS Leitung setzen
rcall toogleen
cbi lcd_port, rs ;und die RS Leitung rücksetzen
andi tmp2, 0b00001111 ;so und jetzt die 4 Lowbits fürn Port zuschneiden
out lcd_port, tmp2 ;und ab ins LCD
sbi lcd_port, rs ;RS Leitung setzen
rcall toogleen
rcall waitus50 ;und wieder 50µS warten
cbi lcd_port, rs ;RS Leitung rücksetzen
ret
;###[ lcd_com Befehle senden ]################################################## ###
lcd_com:
mov tmp2, tmp ;Befehlsbyte kopieren
swap tmp ;Nippeltausch ( Hightbits zuerst senden )
andi tmp, 0b00001111 ;es dürfen ja nur die Pin0 - 4 gesetzt werden
out lcd_port, tmp ;und ab ins LCD damit
rcall toogleen
andi tmp2, 0b00001111 ;so und jetzt die 4 Lowbits fürn Port zuschneiden
out lcd_port, tmp2 ;und ab ins LCD
rcall toogleen
rcall waitus50 ;und wieder 50µS warten
ret
;###[ lcd_cls Display löschen ]################################################## ##
lcd_cls:
ldi tmp, (1<<db0) ;Display löschen
rcall lcd_com
rcall waitms5
ret
; WARTESCHAUFEN UND SONST. SUBs
; =================================
;---[ Enable Set/Reset ]------------------------------------------------------------
toogleen:
sbi lcd_port,en ;Enable auf High setzen
nop ;1µSec Warten
nop
nop
nop
cbi lcd_port,en ;Enable au Low setzen
ret
;---[ 50µS warten ]-----------------------------------------------------------------
waitus50: ;Genau 50µS warten ( 190 + 10 Clocks bei 4MHz )
ldi tmp, $3F
WGLP3: dec tmp
brne WGLP3
nop
ret
;---[ 5mS warten ]------------------------------------------------------------------
waitms5: ;Ganz genau 5ms warten (19990 + 10 Clocks bei 4MHz)
ldi tmp, $1E
WGLP0: ldi tmp2, $DD
WGLP1: dec tmp2
brne WGLP1
dec tmp
brne WGLP0
ldi tmp, $03
WGLP2: dec tmp
brne WGLP2
nop
ret
Bin daran meine Programmierkünste anzuzweifeln, helft mir bitte!!!