Code:
.include "m8def.inc"
.def tmp = r16
.def tmp2 = r17
.def status_reg = r18
;BIT 0 zeigt an, ob PINB,1 während der ISR LOW war, dann = 1
;BIT 1 warten auf dcf Anfang =1 => freigabe
;Bit 2 Fehlerbit
.def pw = r19
.def pw2 = r20
.def pw_alt = r21
.def dcf_shift_reg = r24
.def sreg_save = r25
.equ dcf_BIT_counter = 104
.equ eins = 1
.equ zwei = 2
.equ vier = 4
.equ acht = 8
.equ zehn = 10
.equ zwanzig = 20
.equ vierzig = 40
.org 0x000
rjmp reset
.org OC1Aaddr
rjmp timer1_int
;*****************************************
;*****************************************
; Pointer Z
;
; ms = RAM 100
; sc = RAM 101
; min = RAM 102
; stunde = RAM 103
; dcf_BIT_counter = RAM 104
;
;******************************************
;******************************************
; Pointer Y
; dcf BIT 0-7 = RAM 105
; dcf BIT 8-15 = RAM 106
; dcf BIT 16-23 = RAM 107
; dcf BIT 24-31 = RAM 107
; dcf BIT 32-39 = RAM 108
; dcf BIT 40-47 = RAM 109
; dcf BIT 48-55 = RAM 110
; dcf BIT 56-59 = RAM 111
reset:
;Stack wird bei Interrupts benötigt!
ldi tmp,HIGH(RAMEND)
out SPH,tmp
ldi tmp,LOW(RAMEND)
out SPL,tmp
ldi tmp,0xFF
out DDRD,tmp
ldi tmp,0
ldi r28,105
ldi r29,0
ldi r31,0
ldi r30,100
st Z+,tmp
st Z+,tmp
st Z+,tmp
st Z+,tmp
st Z,tmp
ldi r30,100
ldi tmp,0
out DDRC,tmp
ldi tmp,0b00110000
out PORTC,tmp
ldi tmp,0
out DDRB,tmp
ldi tmp,0
out PORTB,tmp
ldi tmp,0b00110000
out TIMSK,tmp
ldi tmp,0b00000010
out OCR1AH,tmp
ldi r17,0b01110001
out OCR1AL,r17
ldi tmp,0b00000000
out TCCR1A,tmp
ldi tmp,0b00001011
out TCCR1B,tmp
ldi r17,0
ldi status_reg,0
ldi r28,105
ldi dcf_shift_reg,0
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y,dcf_shift_reg
ldi r28,105
sbi PORTD,7
ldi pw_alt,0
sei
main:
;**********************************
; Funktion dcf_einholen wird aufgerufen, wenn
; pw > 9 und am ISR Anfang keinSignal da war
; pw wird in dcf_einholen gelöscht
;pw kann nur erhöht werden, wenn
;lange Pause da war => keine Abfrage von
;Bit 1 im status_reg nötig
cpi pw,5
brlo dcf_nicht_einholen
sbrc status_reg,0b00000000;
rjmp dcf_nicht_einholen
rcall dcf_einholen
;**********************************
; out PORTD,r28
sbrc status_reg,0b00000100
rcall dcf_auswerten
dcf_nicht_einholen:
sbis PINC,5
ori status_reg,0b00100000
rjmp main
fehlerroutine:
ldi status_reg,0
ldi r28,105
st Y,status_reg
ldi r30,104
st Z,status_reg
ldi r30,100
ldi pw,0
ldi pw2,0
ret
dcf_einholen:
/*
1.) prüft Pulsweite auf >< 150 ms
2.) erhöht Y Pointer, wenn ein Byte voll ist
3.) speichert bei "überlauf" von bit_counter=8 bit_counter = 0 ab
24 CK´s inclusive rcall
*/
ldi r30,dcf_BIT_counter
ld tmp,Z
ld dcf_shift_reg,Y;
lsr dcf_shift_reg
cpi pw,16
brlo log_null
ori dcf_shift_reg,0b10000000
log_null:
st Y,dcf_shift_reg
sbrs tmp,0b00000011
rjmp vollmachen
ldi tmp,0
st Z,tmp
inc r28
ldi dcf_shift_reg,0
vollmachen:
ldi pw,0
ldi r30,100
inc pw_alt
cpi pw_alt,59
brne mehr1
ori status_reg,0b00010000
mehr1:
ret
dcf_auswerten:
ldi r30,dcf_BIT_counter
ldi tmp,0
st Z,tmp
andi status_reg,0b11101101; löschen der Freigabe von Pause_war_da
; und Aufruf von dcf_auswerten
ldi pw_alt,0
/*
wertet die Bitmuster in RAM 107 bis 109 in Minuten und Stunden aus
81 CK´s inclusive rcall
*/
;***************************
; Minuten
ldi r28,107
ld tmp,Y
inc r28;lädt von 107 dann inc zu 108
ldi r22,0
ldi tmp2,1
sbrc tmp,0b00000101
add r22,tmp2
ldi tmp2,2
sbrc tmp,0b00000110
add r22,tmp2
ldi tmp2,4
sbrc tmp,0b00000111
add r22,tmp2
ld tmp,Y
inc r28;lädt von 108 dann inc zu 109
ldi tmp2,8
sbrc tmp,0b00000000
add r22,tmp2
ldi tmp2,10
sbrc tmp,0b00000001
add r22,tmp2
ldi tmp2,20
sbrc tmp,0b00000010
add r22,tmp2
ldi tmp2,40
sbrc tmp,0b00000011
add r22,tmp2
;out PORTD,r22
;***************************
;***************************
; Stunde
ldi tmp2,eins
sbrc tmp,0b00000101
add r23,tmp2
ldi tmp2,2
sbrc tmp,0b00000110
add r23,tmp2
ldi tmp2,4
sbrc tmp,0b00000111
add r23,tmp2
ld tmp,Y ;lädt von 109
ldi tmp2,8
sbrc tmp,0b00000000
add r23,tmp2
ldi tmp2,10
sbrc tmp,0b00000001
add r23,tmp2
ldi tmp2,20
sbrc tmp,0b00000010
add r23,tmp2
ldi r22,0
ldi r23,0
;***************************
ldi r28,105
ldi dcf_shift_reg,0
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y,dcf_shift_reg
ldi r28,105
out PORTD,status_reg
sbi PORTD,6
ret
timer1_int:
in sreg_save,SREG
sbrs status_reg,0b00000101
rjmp ignore
;****************************
; setzt Bit 0 in status_reg, wenn Signal da (PINB_0 HIGH) ist
; setzte Bit 3 in status_reg auf rising edge
sbis PINB,0
rjmp kein_signal_an_pinb0
sbrs status_reg,0b00000000
ori status_reg,0b00001000
ori status_reg,0b00000001
rjmp signal_da
kein_signal_an_pinb0:
andi status_reg,0b11111110
signal_da:
;**************************
;***************************
; ausführen wenn kein Signal
sbrc status_reg,0b00000000
rjmp warten_auf_pause
inc pw2
cpi pw2,100
brlo warten_auf_pause
ldi r22,0
sbrc status_reg,0b00000001
rjmp fehlerbit_setzten
ori status_reg,0b00000010
ldi pw2,0
rjmp warten_auf_pause
fehlerbit_setzten:
ori status_reg,0b00000100
ldi pw2,0
rjmp war_keins_da
warten_auf_pause:
war_keins_da:
;***************************
;***************************
;ausführen, wenn zu ISR Anfang Signal da war und
;lange Pause da war
sbrs status_reg,0b00000000
rjmp warten_auf_signal
sbrs status_reg,0b00000001
rjmp warten_auf_signal
inc pw
ldi pw2,0
warten_auf_signal:
sbrc status_reg,0b00000000
ldi pw2,0
sbrs status_reg,0b00000011
rjmp fix
ldi r30,dcf_BIT_counter
ld tmp,Z
inc tmp
st Z,tmp
andi status_reg,0b11110111
fix:
;out PORTD,status_reg
ignore:
;****************** Zählen der ms RAM 100
ldi r30,100
ld tmp,Z
inc tmp
st Z,tmp
cpi tmp,100
brlo mehr
ldi tmp,0
st Z+,tmp
;******************
;****************** Zählen der sec RAM 101
ld tmp,Z
inc tmp
st Z,tmp
cpi tmp,60
brlo mehr
ldi tmp,0
st Z,tmp
inc r30
;******************
;****************** Zählen der min RAM 102
ld tmp,Z
inc tmp
st Z,tmp
cpi tmp,5
brne ignore2
sbr status_reg,0b00100000
cbi PORTD,7
ignore2:
cpi tmp,60
brlo mehr
ldi tmp,0
st Z,tmp
inc r30
;******************
;****************** Zählen der Stunde RAM 103
ld tmp,Z
inc tmp
st Z,tmp
cpi tmp,25
ldi tmp,0
st Z,tmp
;******************
mehr:
ldi r30,100
out SREG,sreg_save
reti
Lesezeichen