orph
30.08.2006, 22:33
Hallo Leute
Ich übe jetzt schon seit mehreren Wochen an meinem "Projekt" herum, doch es will einfach nicht funktionieren.
Ich möchte mit einem PIC16F88 (20Mhz) mit dem Timer 1 eine Uhr konstruieren, die dann die Zeit auf einem LCD ausgibt. Die Genauigkeit der Zeit sowie andere "Erweiterungen" spielt hier noch eine sehr untergeordnete Rolle (kein Auto-Reload von TMR1L/TMR1H...), da ich zuerst einmal das ganze zum Laufen bringen will. Das Programm gibt mir jedoch erst die Grundstellung für die Uhr (00:00:00) und irgendwelche ungewollte, ungeordnete Zeichen auf dem LCD aus => auf gut Deutsch: Chaos. Kann mir jemand hier weiterhelfen und sagen, was ich im nachfolgenden Code falsch gemacht habe? Der Vollständigkeit halber habe ich den ganzen Quellcode incl. Lcd-Ansteuerung etc aufgelistet.
Wäre sehr dankbar.
list p=16F88
#include <p16f88.inc>
__CONFIG _CONFIG1, _CP_OFF & _LVP_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC
; variables
LcdDaten Equ 0x22
LcdStatus Equ 0x23
loops Equ 0x24
loops2 Equ 0x25
stde Equ 0x27
stdz Equ 0x2C
mine Equ 0x2D
minz Equ 0x30
seke Equ 0x31 ; einerstelle sekunden
sekz Equ 0x32 ;zehnerstelle sekunden
w_copy Equ 0x33
s_copy Equ 0x34
copyw Equ 0x20
copys Equ 0x21
; constants
PORTC Equ PORTB
PORTD Equ PORTB
;pins LCD
#define LcdE PORTB, 0
#define LcdRw PORTB, 3
#define LcdRs PORTB, 2
org 0x00
goto Main
org 0x04
ISR ;interupt service routine
movwf copyw
swapf STATUS, W
bcf STATUS, RP0
movwf copys
incf seke, f ;seke +1
movfw seke
sublw .10 ;seke -10 ;result negativ => z=0
btfss STATUS, Z ;test z, if z=1 => skip next order
call printseke
call clearseke
incf sekz, f
movf sekz, w
sublw .6
btfss STATUS, Z
call printsekz
call clearsekz
incf mine, f
movf mine, w
sublw .10
btfss STATUS, Z
call printmine
call clearmine
incf minz, f
movf minz, w
sublw .6
btfss STATUS, Z
call printminz
call clearminz
incf stde, f
movf stde, w
sublw .10
btfss STATUS, Z
call printstde
call clearstde
incf stdz, f
movf stdz, w
sublw .10
btfss STATUS, Z
call printstdz
call clearstdz
goto clearstdz
ISRend ;interupt end routine
bcf STATUS, RP0
bcf PIR1, TMR1IF ;clear interupt flag
swapf copys, w
movwf STATUS
swapf copyw, f
swapf copyw, w
retfie
Init
bcf INTCON, GIE
bcf INTCON, PEIE
bsf STATUS, RP0
movlw B'00000000'
movwf TRISB
movlw B'00000000'
movwf ANSEL
bcf STATUS, RP0
return
InitTimer
bcf STATUS, RP0
movlw B'00110101' ;prescaler: 1:8; internal clock; not synchronize; Timer1 enabled
movwf T1CON
bsf STATUS, RP0
bsf PIE1, TMR1IE
bcf STATUS, RP0
bsf INTCON, GIE
bsf INTCON, PEIE
return
Main
call Init
call InitLCD
call InitTimer
WAIT
wai movlw .249
movwf loops2
wai2 nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto wai2
decfsz loops, F
goto wai
return
InitLCD
movlw D'25'
movwf loops
call WAIT
movlw B'00110000'
movwf PORTB
bsf LcdE
nop
bcf LcdE
movlw D'10'
movwf loops
call WAIT
movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit
movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
movlw B'11000100'
call OutLcdControl
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw ':'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw ':'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
return
Control8Bit
movwf PORTB
bsf LcdE
nop
bcf LcdE
movlw D'10'
movwf loops
call WAIT
return
LcdBusy
bsf STATUS, RP0
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf LcdRs
bsf LcdRw
bsf LcdE
nop
movf PORTD, w
movwf LcdStatus
bcf LcdE
nop
bsf LcdE
nop
bcf LcdE
btfsc LcdStatus, 7
goto BusyLoop
bcf LcdRw
bsf STATUS, RP0
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
return
OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdE
nop
bcf LcdE
swapf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdE
nop
bcf LcdE
return
OutLcdDaten
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdRs
bsf LcdE
nop
bcf LcdE
swapf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdRs
bsf LcdE
nop
bcf LcdE
bcf LcdRs
return
clearseke ;ausgabe von seke, mit reset der stelle auf 0
movlw b'11001011'
call OutLcdControl
clrf seke
movfw seke
iorlw '0'
call OutLcdDaten
goto ISRend
clearsekz
movlw b'11001010'
call OutLcdControl
clrf sekz
movfw sekz
iorlw '0'
call OutLcdDaten
goto ISRend
clearmine
movlw b'11001000'
call OutLcdControl
clrf mine
movfw mine
iorlw '0'
call OutLcdDaten
goto ISRend
clearminz
movlw b'11000111'
call OutLcdControl
clrf minz
movfw minz
iorlw '0'
call OutLcdDaten
goto ISRend
clearstde
movlw b'11000101'
call OutLcdControl
clrf stde
movfw stde
iorlw '0'
call OutLcdDaten
goto ISRend
clearstdz
movlw b'11000100'
call OutLcdControl
clrf stdz
movfw stdz
iorlw '0'
call OutLcdDaten
goto ISRend
printseke ; ausgabe von seke & beenden der ISR
movlw b'11001011'
call OutLcdControl
movfw seke
iorlw '0'
call OutLcdDaten
goto ISRend
printsekz
movlw b'11001010'
call OutLcdControl
movfw sekz
iorlw '0'
call OutLcdDaten
goto ISRend
printmine
movlw b'11001000'
call OutLcdControl
movfw mine
iorlw '0'
call OutLcdDaten
goto ISRend
printminz
movlw b'11000111'
call OutLcdControl
movfw minz
iorlw '0'
call OutLcdDaten
goto ISRend
printstde
movlw b'11000101'
call OutLcdControl
movfw stde
iorlw '0'
call OutLcdDaten
goto ISRend
printstdz
movlw b'11000100'
call OutLcdControl
movfw stdz
iorlw '0'
call OutLcdDaten
goto ISRend
end
(Sorry für die lückenhaften Kommentare im Code.)
Auch einen Link zu einem funktionnierenden Programm, das Timer1 verwendet, wäre sehr hilfreich, damit ich vergleichen könnte und so ev. den Fehler finden könnte. (bei google habe ich nichts gefunden)
Greez orph
Ich übe jetzt schon seit mehreren Wochen an meinem "Projekt" herum, doch es will einfach nicht funktionieren.
Ich möchte mit einem PIC16F88 (20Mhz) mit dem Timer 1 eine Uhr konstruieren, die dann die Zeit auf einem LCD ausgibt. Die Genauigkeit der Zeit sowie andere "Erweiterungen" spielt hier noch eine sehr untergeordnete Rolle (kein Auto-Reload von TMR1L/TMR1H...), da ich zuerst einmal das ganze zum Laufen bringen will. Das Programm gibt mir jedoch erst die Grundstellung für die Uhr (00:00:00) und irgendwelche ungewollte, ungeordnete Zeichen auf dem LCD aus => auf gut Deutsch: Chaos. Kann mir jemand hier weiterhelfen und sagen, was ich im nachfolgenden Code falsch gemacht habe? Der Vollständigkeit halber habe ich den ganzen Quellcode incl. Lcd-Ansteuerung etc aufgelistet.
Wäre sehr dankbar.
list p=16F88
#include <p16f88.inc>
__CONFIG _CONFIG1, _CP_OFF & _LVP_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC
; variables
LcdDaten Equ 0x22
LcdStatus Equ 0x23
loops Equ 0x24
loops2 Equ 0x25
stde Equ 0x27
stdz Equ 0x2C
mine Equ 0x2D
minz Equ 0x30
seke Equ 0x31 ; einerstelle sekunden
sekz Equ 0x32 ;zehnerstelle sekunden
w_copy Equ 0x33
s_copy Equ 0x34
copyw Equ 0x20
copys Equ 0x21
; constants
PORTC Equ PORTB
PORTD Equ PORTB
;pins LCD
#define LcdE PORTB, 0
#define LcdRw PORTB, 3
#define LcdRs PORTB, 2
org 0x00
goto Main
org 0x04
ISR ;interupt service routine
movwf copyw
swapf STATUS, W
bcf STATUS, RP0
movwf copys
incf seke, f ;seke +1
movfw seke
sublw .10 ;seke -10 ;result negativ => z=0
btfss STATUS, Z ;test z, if z=1 => skip next order
call printseke
call clearseke
incf sekz, f
movf sekz, w
sublw .6
btfss STATUS, Z
call printsekz
call clearsekz
incf mine, f
movf mine, w
sublw .10
btfss STATUS, Z
call printmine
call clearmine
incf minz, f
movf minz, w
sublw .6
btfss STATUS, Z
call printminz
call clearminz
incf stde, f
movf stde, w
sublw .10
btfss STATUS, Z
call printstde
call clearstde
incf stdz, f
movf stdz, w
sublw .10
btfss STATUS, Z
call printstdz
call clearstdz
goto clearstdz
ISRend ;interupt end routine
bcf STATUS, RP0
bcf PIR1, TMR1IF ;clear interupt flag
swapf copys, w
movwf STATUS
swapf copyw, f
swapf copyw, w
retfie
Init
bcf INTCON, GIE
bcf INTCON, PEIE
bsf STATUS, RP0
movlw B'00000000'
movwf TRISB
movlw B'00000000'
movwf ANSEL
bcf STATUS, RP0
return
InitTimer
bcf STATUS, RP0
movlw B'00110101' ;prescaler: 1:8; internal clock; not synchronize; Timer1 enabled
movwf T1CON
bsf STATUS, RP0
bsf PIE1, TMR1IE
bcf STATUS, RP0
bsf INTCON, GIE
bsf INTCON, PEIE
return
Main
call Init
call InitLCD
call InitTimer
WAIT
wai movlw .249
movwf loops2
wai2 nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto wai2
decfsz loops, F
goto wai
return
InitLCD
movlw D'25'
movwf loops
call WAIT
movlw B'00110000'
movwf PORTB
bsf LcdE
nop
bcf LcdE
movlw D'10'
movwf loops
call WAIT
movlw B'00110000'
call Control8Bit
movlw B'00110000'
call Control8Bit
movlw B'00100000'
call Control8Bit
movlw B'00000001'
call OutLcdControl
movlw B'00101000'
call OutLcdControl
movlw B'00001000'
call OutLcdControl
movlw B'00000110'
call OutLcdControl
movlw B'00000011'
call OutLcdControl
movlw B'00001111'
call OutLcdControl
movlw B'11000100'
call OutLcdControl
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw ':'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw ':'
call OutLcdDaten
movlw '0'
call OutLcdDaten
movlw '0'
call OutLcdDaten
return
Control8Bit
movwf PORTB
bsf LcdE
nop
bcf LcdE
movlw D'10'
movwf loops
call WAIT
return
LcdBusy
bsf STATUS, RP0
movlw B'11110000'
iorwf TRISB, f
bcf STATUS, RP0
BusyLoop
bcf LcdRs
bsf LcdRw
bsf LcdE
nop
movf PORTD, w
movwf LcdStatus
bcf LcdE
nop
bsf LcdE
nop
bcf LcdE
btfsc LcdStatus, 7
goto BusyLoop
bcf LcdRw
bsf STATUS, RP0
movlw B'00001111'
andwf TRISB, f
bcf STATUS, RP0
return
OutLcdControl
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdE
nop
bcf LcdE
swapf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdE
nop
bcf LcdE
return
OutLcdDaten
movwf LcdDaten
call LcdBusy
movf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdRs
bsf LcdE
nop
bcf LcdE
swapf LcdDaten, w
andlw H'F0'
movwf PORTD
bsf LcdRs
bsf LcdE
nop
bcf LcdE
bcf LcdRs
return
clearseke ;ausgabe von seke, mit reset der stelle auf 0
movlw b'11001011'
call OutLcdControl
clrf seke
movfw seke
iorlw '0'
call OutLcdDaten
goto ISRend
clearsekz
movlw b'11001010'
call OutLcdControl
clrf sekz
movfw sekz
iorlw '0'
call OutLcdDaten
goto ISRend
clearmine
movlw b'11001000'
call OutLcdControl
clrf mine
movfw mine
iorlw '0'
call OutLcdDaten
goto ISRend
clearminz
movlw b'11000111'
call OutLcdControl
clrf minz
movfw minz
iorlw '0'
call OutLcdDaten
goto ISRend
clearstde
movlw b'11000101'
call OutLcdControl
clrf stde
movfw stde
iorlw '0'
call OutLcdDaten
goto ISRend
clearstdz
movlw b'11000100'
call OutLcdControl
clrf stdz
movfw stdz
iorlw '0'
call OutLcdDaten
goto ISRend
printseke ; ausgabe von seke & beenden der ISR
movlw b'11001011'
call OutLcdControl
movfw seke
iorlw '0'
call OutLcdDaten
goto ISRend
printsekz
movlw b'11001010'
call OutLcdControl
movfw sekz
iorlw '0'
call OutLcdDaten
goto ISRend
printmine
movlw b'11001000'
call OutLcdControl
movfw mine
iorlw '0'
call OutLcdDaten
goto ISRend
printminz
movlw b'11000111'
call OutLcdControl
movfw minz
iorlw '0'
call OutLcdDaten
goto ISRend
printstde
movlw b'11000101'
call OutLcdControl
movfw stde
iorlw '0'
call OutLcdDaten
goto ISRend
printstdz
movlw b'11000100'
call OutLcdControl
movfw stdz
iorlw '0'
call OutLcdDaten
goto ISRend
end
(Sorry für die lückenhaften Kommentare im Code.)
Auch einen Link zu einem funktionnierenden Programm, das Timer1 verwendet, wäre sehr hilfreich, damit ich vergleichen könnte und so ev. den Fehler finden könnte. (bei google habe ich nichts gefunden)
Greez orph