Stefan_84
14.07.2008, 14:06
Guten Tag!
Wie schon in einem früheren Thread erwähnt möchte ich meine Schaltung mit einem LC-Display austatten um Akkuspannung, Zeit usw. abzulesen.
Es handelt sich dabei um ein 2Zeiliges Display mit je 16 Zeichen. Die Datenleitungen hängen auf PortC, die Steuerleitungen auf PortE (E0=Ena, E1=R/W, E2=RS)
Hab jetzt mal ein Testprogramm gemacht damit ich den Umgang mit dem Display lernen kann. Das folgende Programm funktioniert und gibt auf dem Display "AB" aus.
;************************************************* ****************************
;*
;* DATEINAME : disp1.asm
;* TITEL : Display ansteuern
;* DATUM : 14.7.08
;* AUTOR : STK
;* VERSION : 1.0
;*
;*
;************************************************* ****************************
.include "m8515def.inc"
;--KONSTANTENDEKLARATION---------------------------------------------
; status register bits
.equ CarryFlag = 0
.equ ZeroFlag = 1
.equ NegativeFlag = 2
.equ TwosFlag = 3
.equ SignFlag = 4
.equ HalfCarryFlag = 5
.equ TransferFlag = 6
.equ GlobalFlag = 7
.equ Frequenz = 4000000
.equ Teiler = 4000
;--VARIABLENDEKLARATION----------------------------------------
.def work = R16 ;Temp. Variable
.def zaehler = R17
.def sreg_save = R18
.CSEG
.org 0x0000
rjmp MAIN ;Reset
rjmp UnusedInt_ISR ;Ext. Int0
rjmp UnusedInt_ISR ;Ext. Int1
rjmp UnusedInt_ISR ;Timer1 Capture Event
rjmp timer ;Timer1 Compare Match A
rjmp UnusedInt_ISR ;Timer1 Compare Match B
rjmp UnusedInt_ISR ;Timer1 Overflow
rjmp UnusedInt_ISR ;Timer0 Overflow
rjmp UnusedInt_ISR ;Serial Transfer Complete
rjmp UnusedInt_ISR ;USART Rx Complete
rjmp UnusedInt_ISR ;USART Data Reg. Empty
rjmp UnusedInt_ISR ;USART Tx Complete
rjmp UnusedInt_ISR ;Analog Comperator
rjmp UnusedInt_ISR ;Ext. Int Request 2
rjmp UnusedInt_ISR ;Timer0 Compare Match
rjmp UnusedInt_ISR ;EEPRom Ready
rjmp UnusedInt_ISR ;Store Program memory ready
UnusedInt_ISR: reti
;--Hauptprogramm------------------------------------------------
MAIN:
;Stackpointer initialisieren
ldi work,low (RAMEND) ; RAMEND ist eine im include file vorgegebene Konstante,
out SPL,work
ldi work, high(RAMEND)
out SPH,work
rjmp init
Main_loop:
;Hauptprogramm
;Display Position 1
ldi work, 0b001
out porte, work
ldi work, 0b10000000
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait100: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait100
ldi work, 0b000
out porte, work
;Schreibe A auf Display
ldi work, 0b101
out porte, work
ldi work, 0b01000001
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait10: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait10
ldi work, 0b100 ;Daten in Textpuffer geschrieben
out porte, work
;Display Position 2
ldi work, 0b001
out porte, work
ldi work, 0b10000001
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait101: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait101
ldi work, 0b000
out porte, work
;Schreibe B auf Display
ldi work, 0b101
out porte, work
ldi work, 0b01000010
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait11: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait11
ldi work, 0b100 ;Daten in Textpuffer geschrieben
out porte, work
rcall ende
rjmp Main_loop;
;--Unterprogramme-----------------------------------------------------
init:
clr zaehler
ser work
out ddrc, work ;Ausgang: Display D0-D7
out ddre, work ;Ausgang: Display Ena, RW, RS
clr work
out tccr1a, work
ldi work, 0b00001001
out tccr1b, work
ldi work, 0b01100000 ;Timer Einstellungen
out tIMSK, work
ldi work, HIGH(Frequenz / Teiler)
out ocr1ah, work
ldi work, LOW(Frequenz / Teiler)
out ocr1al, work
sei
;warten
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait0: ;>1,64ms warten
ldi work, 0b00111100
cpse work, zaehler
rjmp wait0
rcall init_disp
rjmp main_loop
init_disp:
ldi work, 0b000
out porte, work
ldi work, 0b00000001 ;Display löschen
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait1: ;>1,64ms warten
ldi work, 0b00001000
cpse work, zaehler
rjmp wait1
ldi work, 0b000
out porte, work
ldi work, 0b00000010 ;Cursor auf Anfang
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait3: ;>1,64ms warten
ldi work, 0b00001000
cpse work, zaehler
rjmp wait3
ldi work, 0b000
out porte, work
ldi work, 0b00000100 ;Entry mdoe
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait4: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait4
ldi work, 0b000
out porte, work
ldi work, 0b00001100 ;Display ein
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait5: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait5
ldi work, 0b000
out porte, work
ldi work, 0b00010100 ;Cursor Shift
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait8: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait8
ldi work, 0b000
out porte, work
ldi work, 0b00111000 ;Function set
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait2: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait2
ldi work, 0b000
out porte, work
ldi work, 0b01000000 ;CGRAM
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait6: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait6
ldi work, 0b000
out porte, work
ldi work, 0b10000000 ;DDRAM
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait7: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait7
ldi work, 0b000
out porte, work
ret
ende:
rjmp ende
ret
;*********Interrupt************
timer:
in sreg_save, sreg
inc zaehler
out sreg, sreg_save
reti
Mir kommt jetzt aber vor das das etwas viel Code ist um 2 Zeichen auszugeben, daher wollte ich mal nachfragen ob ich das schon richtig mache und ob das vielleicht irgendwie kompakter oder eleganter gelöst werden kann.
mfg
Stefan
Wie schon in einem früheren Thread erwähnt möchte ich meine Schaltung mit einem LC-Display austatten um Akkuspannung, Zeit usw. abzulesen.
Es handelt sich dabei um ein 2Zeiliges Display mit je 16 Zeichen. Die Datenleitungen hängen auf PortC, die Steuerleitungen auf PortE (E0=Ena, E1=R/W, E2=RS)
Hab jetzt mal ein Testprogramm gemacht damit ich den Umgang mit dem Display lernen kann. Das folgende Programm funktioniert und gibt auf dem Display "AB" aus.
;************************************************* ****************************
;*
;* DATEINAME : disp1.asm
;* TITEL : Display ansteuern
;* DATUM : 14.7.08
;* AUTOR : STK
;* VERSION : 1.0
;*
;*
;************************************************* ****************************
.include "m8515def.inc"
;--KONSTANTENDEKLARATION---------------------------------------------
; status register bits
.equ CarryFlag = 0
.equ ZeroFlag = 1
.equ NegativeFlag = 2
.equ TwosFlag = 3
.equ SignFlag = 4
.equ HalfCarryFlag = 5
.equ TransferFlag = 6
.equ GlobalFlag = 7
.equ Frequenz = 4000000
.equ Teiler = 4000
;--VARIABLENDEKLARATION----------------------------------------
.def work = R16 ;Temp. Variable
.def zaehler = R17
.def sreg_save = R18
.CSEG
.org 0x0000
rjmp MAIN ;Reset
rjmp UnusedInt_ISR ;Ext. Int0
rjmp UnusedInt_ISR ;Ext. Int1
rjmp UnusedInt_ISR ;Timer1 Capture Event
rjmp timer ;Timer1 Compare Match A
rjmp UnusedInt_ISR ;Timer1 Compare Match B
rjmp UnusedInt_ISR ;Timer1 Overflow
rjmp UnusedInt_ISR ;Timer0 Overflow
rjmp UnusedInt_ISR ;Serial Transfer Complete
rjmp UnusedInt_ISR ;USART Rx Complete
rjmp UnusedInt_ISR ;USART Data Reg. Empty
rjmp UnusedInt_ISR ;USART Tx Complete
rjmp UnusedInt_ISR ;Analog Comperator
rjmp UnusedInt_ISR ;Ext. Int Request 2
rjmp UnusedInt_ISR ;Timer0 Compare Match
rjmp UnusedInt_ISR ;EEPRom Ready
rjmp UnusedInt_ISR ;Store Program memory ready
UnusedInt_ISR: reti
;--Hauptprogramm------------------------------------------------
MAIN:
;Stackpointer initialisieren
ldi work,low (RAMEND) ; RAMEND ist eine im include file vorgegebene Konstante,
out SPL,work
ldi work, high(RAMEND)
out SPH,work
rjmp init
Main_loop:
;Hauptprogramm
;Display Position 1
ldi work, 0b001
out porte, work
ldi work, 0b10000000
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait100: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait100
ldi work, 0b000
out porte, work
;Schreibe A auf Display
ldi work, 0b101
out porte, work
ldi work, 0b01000001
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait10: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait10
ldi work, 0b100 ;Daten in Textpuffer geschrieben
out porte, work
;Display Position 2
ldi work, 0b001
out porte, work
ldi work, 0b10000001
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait101: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait101
ldi work, 0b000
out porte, work
;Schreibe B auf Display
ldi work, 0b101
out porte, work
ldi work, 0b01000010
out portc, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait11: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait11
ldi work, 0b100 ;Daten in Textpuffer geschrieben
out porte, work
rcall ende
rjmp Main_loop;
;--Unterprogramme-----------------------------------------------------
init:
clr zaehler
ser work
out ddrc, work ;Ausgang: Display D0-D7
out ddre, work ;Ausgang: Display Ena, RW, RS
clr work
out tccr1a, work
ldi work, 0b00001001
out tccr1b, work
ldi work, 0b01100000 ;Timer Einstellungen
out tIMSK, work
ldi work, HIGH(Frequenz / Teiler)
out ocr1ah, work
ldi work, LOW(Frequenz / Teiler)
out ocr1al, work
sei
;warten
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait0: ;>1,64ms warten
ldi work, 0b00111100
cpse work, zaehler
rjmp wait0
rcall init_disp
rjmp main_loop
init_disp:
ldi work, 0b000
out porte, work
ldi work, 0b00000001 ;Display löschen
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait1: ;>1,64ms warten
ldi work, 0b00001000
cpse work, zaehler
rjmp wait1
ldi work, 0b000
out porte, work
ldi work, 0b00000010 ;Cursor auf Anfang
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait3: ;>1,64ms warten
ldi work, 0b00001000
cpse work, zaehler
rjmp wait3
ldi work, 0b000
out porte, work
ldi work, 0b00000100 ;Entry mdoe
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait4: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait4
ldi work, 0b000
out porte, work
ldi work, 0b00001100 ;Display ein
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait5: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait5
ldi work, 0b000
out porte, work
ldi work, 0b00010100 ;Cursor Shift
out portc, work
ldi work, 0b001
out porte, work
clr zaehler
clr work
out TCNT1L, work
out TCNT1H, work
wait8: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait8
ldi work, 0b000
out porte, work
ldi work, 0b00111000 ;Function set
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait2: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait2
ldi work, 0b000
out porte, work
ldi work, 0b01000000 ;CGRAM
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait6: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait6
ldi work, 0b000
out porte, work
ldi work, 0b10000000 ;DDRAM
out portc, work
ldi work, 0b001
out porte, work
clr work
clr zaehler
out TCNT1L, work
out TCNT1H, work
wait7: ;>40us warten
ldi work, 0b00000001
cpse work, zaehler
rjmp wait7
ldi work, 0b000
out porte, work
ret
ende:
rjmp ende
ret
;*********Interrupt************
timer:
in sreg_save, sreg
inc zaehler
out sreg, sreg_save
reti
Mir kommt jetzt aber vor das das etwas viel Code ist um 2 Zeichen auszugeben, daher wollte ich mal nachfragen ob ich das schon richtig mache und ob das vielleicht irgendwie kompakter oder eleganter gelöst werden kann.
mfg
Stefan