1 | .include "tn85def.inc"
|
2 |
|
3 | .equ LEDROT = 0
|
4 | ...
|
5 | .equ LEDGRUEN = 2
|
6 | ...
|
7 | .equ DCF77DATA = 4
|
8 |
|
9 | ...
|
10 |
|
11 | .def dcf77_input = r13
|
12 | ...
|
13 | .def dcf77_count = r15
|
14 | .def temp = r16
|
15 | ...
|
16 | .def dcf77_reg0 = r20
|
17 | .def dcf77_reg1 = r21
|
18 | .def dcf77_reg2 = r22
|
19 | .def dcf77_reg3 = r23
|
20 |
|
21 | ...
|
22 |
|
23 | .org 0x0000
|
24 | rjmp reset
|
25 |
|
26 | ...
|
27 |
|
28 | .org OC0Aaddr
|
29 | rjmp timer0_comp
|
30 |
|
31 | reset:
|
32 | ldi temp, LOW(RAMEND)
|
33 | out SPL, temp
|
34 | ldi temp, HIGH(RAMEND)
|
35 | out SPH, temp
|
36 |
|
37 | ldi r16, (1<<LEDROT) | ... (1<<LEDGRUEN) ...
|
38 | out DDRB, r16
|
39 |
|
40 | sbi PORTB, LEDGRUEN
|
41 |
|
42 | ...
|
43 |
|
44 | rcall dcf77_init
|
45 |
|
46 | ldi temp, (1<<MUX1)
|
47 | out ADMUX, temp ; Input=PB4, Aref=Vcc
|
48 | sbi ADCSRA, ADEN
|
49 |
|
50 | ldi temp, (1<<CS01) ; CLK/8
|
51 | out TCCR0B, temp
|
52 | ldi temp, 125 ; 1MHz / 8 / 125 = 1kHz = 10/10ms
|
53 | out OCR0A, temp
|
54 | in temp, TIMSK
|
55 | ori temp, (1<<OCIE0A)
|
56 | out TIMSK, temp
|
57 | clr dcf77_count
|
58 |
|
59 | sei
|
60 |
|
61 | loop:
|
62 | ...
|
63 | rjmp loop
|
64 |
|
65 | ...
|
66 |
|
67 | timer0_comp:
|
68 | push temp
|
69 | in temp, SREG
|
70 | push temp
|
71 | inc dcf77_count
|
72 | ldi temp, 10
|
73 | cp dcf77_count, temp
|
74 | brne timer0_comp_
|
75 | clr dcf77_count
|
76 | clr dcf77_input
|
77 | sbi ADCSRA, ADSC
|
78 | timer0_comp__:
|
79 | sbic ADCSRA, ADSC
|
80 | rjmp timer0_comp__
|
81 | in temp, ADCL
|
82 | in temp, ADCH
|
83 | cpi temp, 0
|
84 | breq timer0_comp___
|
85 | inc dcf77_input
|
86 | timer0_comp___:
|
87 | rcall dcf77_start
|
88 | ...
|
89 | timer0_comp_:
|
90 | pop temp
|
91 | out SREG, temp
|
92 | pop temp
|
93 | reti
|
94 |
|
95 | ...
|
96 |
|
97 | ; DCF77-FUNKUHR BAUSTEIN in AVR Assembler
|
98 |
|
99 |
|
100 | ; Aufruf im 10 mSek. Zyklus (z.B. über Timer-Interrupt).
|
101 |
|
102 | ; Verwendete Register: dcf77_reg0 - dcf77_reg3, R28/R29 sowie R30/31 (Y,Z Pointer).
|
103 |
|
104 | ; Der statische Datenbereich belegt 12 Bytes für den DCF77-Decoder.
|
105 | ; Vor Verwendung ist zu dessen Initialisierung dcf77_init aufzurufen.
|
106 | ; Weitere 8 Bytes enthalten die aktuelle Zeitinformation im BCD-Format
|
107 | ; und können mit zusätzlich installierter Soft-RTC betrieben werden.
|
108 | ; Diese sollte dem Decoder vorangestellt werden und nach Möglichkeit
|
109 | ; auch 1/100 Sekunden zählen (zur Vermeidung von Sek.-Sprüngen beim
|
110 | ; Minutenwechsel).
|
111 |
|
112 | ; Bitte die 20 Variablen wie definiert beieinander lassen.
|
113 | ; Kurzbeschreibung/Initialisierungswerte siehe unten.
|
114 |
|
115 | ; Das DCF77-Signal wird mit Aktiv "Low" an Input PB0 erwartet
|
116 | ; (kann frei nach Bedarf angepasst werden). Die Impulslängenmessung
|
117 | ; erfolgt über die Bestimmung der Signal-Pausenzeiten (in x * 1/100 Sek.).
|
118 |
|
119 |
|
120 | dcf77_start: ldi YL,LOW(DCF77CT) ;alle 10 mSek. aufzurufen
|
121 | ldi YH,HIGH(DCF77CT)
|
122 | ldd dcf77_reg0,Y+0
|
123 | ldd dcf77_reg1,Y+1
|
124 | sbrc dcf77_input, 0 ; Aktiv = 1
|
125 | rjmp dcf77_5
|
126 | cbi PORTB, LEDROT
|
127 | inc dcf77_reg0
|
128 | brne dcf77_3
|
129 | dcf77_1: sbr dcf77_reg1,$80 ;Fehler-Flag setzen
|
130 | std Y+1,dcf77_reg1
|
131 | dcf77_2: clr dcf77_reg0
|
132 | dcf77_3: std Y+0,dcf77_reg0
|
133 | dcf77_4: ret
|
134 |
|
135 | dcf77_5: tst dcf77_reg0 ;Auswertung fertig?
|
136 | breq dcf77_4 ;Ja!
|
137 | sbi PORTB, LEDROT ; SELBST EINGEFÜGT!!!
|
138 | ldd dcf77_reg2,Y+2 ;Nein!
|
139 | ldd dcf77_reg3,Y+9
|
140 | ldd ZL,Y+10
|
141 | ldd ZH,Y+11
|
142 |
|
143 | cpi dcf77_reg0,196 ;LastBit 0 Obere Zeitgrenze+1 x
|
144 | brsh dcf77_1 ;überschritten -> Fehler
|
145 | cpi dcf77_reg0,187 ;LastBit-Scheide x
|
146 | brsh dcf77_11 ;187-195 = LastBit0
|
147 | cpi dcf77_reg0,178 ;LastBit 1 Untere Zeitgrenze x
|
148 | brsh dcf77_10 ;178-186 = Lastbit1
|
149 |
|
150 | sbrc dcf77_reg1,7 ;Wenn inzwischen Fehler...
|
151 | rjmp dcf77_2 ;dann Abbruch
|
152 |
|
153 | cpi dcf77_reg2,$15 ;STATE < 21:
|
154 | brlo dcf77_8 ;Inc STATE
|
155 |
|
156 | cpi dcf77_reg0,6 ;Störspikegrenze x
|
157 | brlo dcf77_2 ;Störspike wird ignoriert
|
158 | cpi dcf77_reg0,96 ;Datenbit obere Zeitgrenze+1 x
|
159 | brsh dcf77_1 ;überschritten -> Fehler
|
160 | cpi dcf77_reg0,78 ;Datenbit untere Zeitgrenze x
|
161 | brlo dcf77_1 ;unterschritten -> Fehler
|
162 | cpi dcf77_reg0,87 ;Bitscheide x
|
163 | brsh dcf77_6 ;87-95 = Bit0
|
164 | inc dcf77_reg1 ;78-86 = Bit1
|
165 | std Y+1,dcf77_reg1
|
166 | cpi dcf77_reg2,$1c
|
167 | breq dcf77_6 ;Prüfbit Minute!
|
168 | cpi dcf77_reg2,$23
|
169 | breq dcf77_6 ;Prüfbit Stunde!
|
170 | ld dcf77_reg0,Z ;dcf77_reg0 = (aktuelle NEWTIME) Zelle
|
171 | add dcf77_reg0,dcf77_reg3 ;addiere SHIFTER
|
172 | st Z,dcf77_reg0 ;zurückspeichern
|
173 |
|
174 | dcf77_6: lsl dcf77_reg3 ;Bit0/1: SHIFTER um 1 nach links
|
175 | std Y+9,dcf77_reg3
|
176 | cpi dcf77_reg2,$1c
|
177 | brlo dcf77_8 ;Minuten-Zyklus
|
178 | breq dcf77_9 ;Minute Prüfbit
|
179 | cpi dcf77_reg2,$23
|
180 | brlo dcf77_8 ;Stunden-Zyklus
|
181 | breq dcf77_9 ;Stunden-Prüfbit
|
182 | cpi dcf77_reg2,$29
|
183 | brlo dcf77_8
|
184 | breq dcf77_7 ;LastBit TAG
|
185 | cpi dcf77_reg2,$2c
|
186 | brlo dcf77_8
|
187 | breq dcf77_7 ;LastBit WOCHENTAG
|
188 | cpi dcf77_reg2,$31
|
189 | brne dcf77_8
|
190 | dcf77_7: ldi dcf77_reg3,1 ;LastBit MONAT
|
191 | adiw ZH:ZL,1
|
192 | std Y+9,dcf77_reg3
|
193 | std Y+10,ZL
|
194 | std Y+11,ZH
|
195 |
|
196 | dcf77_8: inc dcf77_reg2 ;Inc STATE
|
197 | std Y+2,dcf77_reg2
|
198 | rjmp dcf77_2
|
199 |
|
200 | dcf77_9: sbrc dcf77_reg1,0 ;Prüfbit MIN/STU Auswertung
|
201 | rjmp dcf77_1 ;Prüfbit Fehler
|
202 | rjmp dcf77_7 ;Prüfbit OK
|
203 |
|
204 | dcf77_10: inc dcf77_reg1 ;LastBit = 1: Inc CHECK
|
205 | dcf77_11: cpi dcf77_reg2,$3a ;58 DCF77-Bits erfasst?
|
206 | brne dcf77_init ;unvollständig -> dcf77_init
|
207 | andi dcf77_reg1,$81
|
208 | brne dcf77_init ;Fehlerstatus -> dcf77_init
|
209 |
|
210 | cbi PORTB, LEDGRUEN ; WIRD NICHT ERREICHT!!!
|
211 | ldi dcf77_reg0,6 ;Erfolgreicher Empfang:
|
212 | ld dcf77_reg1,Z ;BCD-Zeitinformation
|
213 | dcf77_12: std Z+11,dcf77_reg1 ;nach MIN...JHR sichern
|
214 | ld dcf77_reg1,-Z
|
215 | dec dcf77_reg0
|
216 | brne dcf77_12
|
217 | std Z+11,dcf77_reg0 ;Sek. = 0 setzen
|
218 | std Z+10,dcf77_reg0 ;1/100 Sek. = 0 setzen
|
219 |
|
220 | dcf77_init: ldi ZL,LOW(DCF77CT) ;DCF77-VARIABLEN RESET
|
221 | ldi ZH,HIGH(DCF77CT)
|
222 | ldi dcf77_reg1,LOW(NEWTIME)
|
223 | ldi dcf77_reg2,HIGH(NEWTIME)
|
224 | ldi dcf77_reg0,$09
|
225 | clr dcf77_reg3
|
226 | dcf77_14: st Z+,dcf77_reg3
|
227 | dec dcf77_reg0
|
228 | brne dcf77_14
|
229 | inc dcf77_reg0
|
230 | st Z+,dcf77_reg0
|
231 | st Z+,dcf77_reg1
|
232 | st Z,dcf77_reg2
|
233 | ret
|
234 |
|
235 | .DSEG
|
236 | ;SRAM Variable Definition Init.Wert Beschreibung
|
237 | ;------------------------------------------------------------------------------
|
238 | DCF77CT: .BYTE 1 ;0 DCF77 Impuls-Pausenzeit-Zähler
|
239 | DCF77CHECK: .BYTE 1 ;0 DCF77 Fehler-Flag + 1-Zähler
|
240 | DCF77STATE: .BYTE 1 ;0 DCF77 Aktuelle Bitnummer
|
241 | NEWTIME: .BYTE 6 ;0,0,0,0,0,0 DCF77 Zeit-Zwischenspeicher
|
242 | DCF77SHIFT: .BYTE 1 ;1 DCF77 Shifter
|
243 | DCF77TAL: .BYTE 1 ;LOW(NEWTIME) DCF77 Pointer auf NEWTIME Low
|
244 | DCF77TAH: .BYTE 1 ;HIGH(NEWTIME) DCF77 Pointer auf NEWTIME High
|
245 | HSEK: .BYTE 1 ;RTC verwaltet BCD 1/100 Sekunde
|
246 | SEK: .BYTE 1 ;RTC verwaltet BCD Sekunde
|
247 | MIN: .BYTE 1 ;RTC verwaltet BCD Minute
|
248 | STU: .BYTE 1 ;RTC verwaltet BCD Stunde
|
249 | TAG: .BYTE 1 ;RTC verwaltet BCD Tag
|
250 | WTAG: .BYTE 1 ;RTC verwaltet BCD Wochentag
|
251 | MON: .BYTE 1 ;RTC verwaltet BCD Monat
|
252 | JHR: .BYTE 1 ;RTC verwaltet BCD Jahr
|