1 | ;Baustelle...
|
2 |
|
3 | ;Zünduhr für Feuerwerks-Sequenzen
|
4 | ;
|
5 |
|
6 |
|
7 | ;Ressourcen:
|
8 |
|
9 | ;Timer0-Ovf: Synchronisieren der LCD-Ausgabe
|
10 | ;Timer1-OCA: Haupttakt für Uhr und Tastenentprellung (10ms)
|
11 | ;Timer2-OC+Ovf: Erzeugung der Ausgangsimpulse für Datenübertragung zu
|
12 | ; Zündverteilern und der Impulse für Ladungspumpen der
|
13 | ; lokalen Zündkreise
|
14 | ;USART: Polling-Betrieb zur seriellen Datenübertragung mit dem PC
|
15 |
|
16 |
|
17 |
|
18 | .nolist ;List der Include-Datei unterdrücken
|
19 | .include"m8515def.inc" ;Hardwaredefinitionen einbinden
|
20 | .list ;Programm listen
|
21 | .listmac ;Makros listen
|
22 | .equ clock=8000000 ;3686400 ;Taktfrequenz des AVR
|
23 |
|
24 | .equ timer0ein=3 ;Bitmuster Timer0 mit Vorteiler 64 (LCD-Sync)
|
25 | .equ timer0swku=254-(clock/3200000) ;Startwert Timer0 für 20µs
|
26 | .equ timer0swla=254-(clock/42667) ;Startwert Timer0 für 1,5ms
|
27 |
|
28 | .equ tim1zu=clock/256 ;Timer1-Interrupt-Takt
|
29 | .equ baud=23 ;USART-Baudrate 9k6
|
30 |
|
31 | .equ tap=pinC ;Port für die Tasten
|
32 | .equ tli=3 ;Taste links
|
33 | .equ tho=2 ;Taste hoch
|
34 | .equ tru=1 ;Taste runter
|
35 | .equ tre=0 ;Taste rechts
|
36 | .equ alltast=(1<<tru)|(1<<tre)|(1<<tho)|(1<<tli) ;Maske aller Tasten
|
37 |
|
38 |
|
39 |
|
40 | .equ vt8=2 ;Timer2-Vorteiler 8 für Bitausgabe
|
41 | .equ nullbit=$c0 ;Impulsbreite für Nullbit (75%) für Bitausgabe
|
42 | .equ einsbit=$40 ;Impulsbreite für Einsbit (25%) für Bitausgabe
|
43 |
|
44 | .dseg ;SRAM-Variablen
|
45 | .org $60 ;Page 0 ($060...$0ff)
|
46 | xptr: .byte 1 ;Lesepointer LCD-Ringbuffer
|
47 | yptr: .byte 1 ;Schreibpointer LCD-Ringbuffer
|
48 | shz: .byte 1 ;Shiftzähler für Ausgabe zum Zündverteiler
|
49 | shl: .byte 1 ;Shift-Byte L für Ausgabe zum Zündverteiler (Data)
|
50 | shh: .byte 1 ;Shift-Byte H für Ausgabe zum Zündverteiler (Chk)
|
51 | shd: .byte 1 ;Datenbyte für Ausgabe zum Zündverteiler (Chk)
|
52 | dsla: .byte 1 ;Datensatz L alt
|
53 | dsha: .byte 1 ;Datensatz H alt
|
54 | snra: .byte 1 ;Schussnummer alt
|
55 | bimua: .byte 1 ;Bitmuster Schuss für PortA
|
56 | bimub: .byte 1 ;Bitmuster Schuss für PortB
|
57 | shibu: .byte 4 ;Shiftbuffer für RX-Parser
|
58 |
|
59 | .org $100 ;Page 1 ($100...$1ff)
|
60 | ringbuffer: .byte 256 ;Ringbuffer für LCD-Ausgabe
|
61 | ;Page 2 ($200...$25f) ist für Stack reserviert
|
62 |
|
63 | .def null=r2 ;immer Null
|
64 | .def ff=r3 ;immer $ff
|
65 | .def srsk=r4 ;SREG-Siko
|
66 | .def lcw=r5 ;LCD-Wartezähler
|
67 | .def zeile=r6 ;aktuelle Zeile
|
68 | .def maxzeile=r7 ;maximal genutzte Zeile
|
69 | .def dsl=r8 ;Zeit L (temp Datensatz)
|
70 | .def dsh=r9 ;Zeit H (temp Datensatz)
|
71 | .def snr=r10 ;Schussnummer (temp Datensatz)
|
72 | .def tz0=r11 ;Tasten-Prellzähler Bit0
|
73 | .def tz1=r12 ;Tasten-Prellzähler Bit1
|
74 | .def tas=r13 ;Tastenstatus (gültig)
|
75 | .def ztl=r14 ;Zeitstempel L
|
76 | .def zth=r15 ;Zeitstempel H
|
77 |
|
78 | .def shift=r18 ;Shiftreg für serielle Ausgabe
|
79 | .def mp=r19 ;Menüpunkt
|
80 | .def teiler=r20 ;Teiler für Timer (1 Sekunde)
|
81 | .def posi=r21
|
82 | .def tfl=r22 ;Tasten-Flags (melden Tastendruck)
|
83 |
|
84 | .def flags=r23 ;diverse Flags
|
85 | .equ neusek=0 ;neue Sekunde
|
86 | .equ v24rx=1 ;RX aktiv (debug...)
|
87 | .equ v24tx=2 ;TX aktiv (debug...)
|
88 | .equ lcdtakt=3 ;Synchronsignal für LCD (1kHz)
|
89 | .equ aktiv=4 ;Uhr läuft
|
90 | .equ schuss=5 ;Schuss ist ausgelöst
|
91 | .equ handschuss=6 ;Schuss wurde von Hand ausgelöst
|
92 |
|
93 | .equ lcdcontroller1=4 ;Flag für Controller 1
|
94 | .equ lcdcontroller2=6 ;Flag für Controller 2
|
95 |
|
96 | .def wl=r24 ;Working L
|
97 | .def wh=r25 ;Working H
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | .macro printsnr ;Schussnummer ausgeben
|
103 | push xl ;verwendete Register sichern
|
104 | mov xl,@0 ;Kopie vom Quellregister
|
105 | rcall lcd_printsnr ;Aufruf...
|
106 | pop xl ;verwendete Register wiederherstellen
|
107 | .endmacro ;
|
108 |
|
109 |
|
110 | .cseg
|
111 |
|
112 | .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 8515
|
113 | rjmp RESET ;Reset Handler
|
114 | rjmp nix;EXT_INT0 ;IRQ0 Handler
|
115 | rjmp nix;EXT_INT1 ;IRQ1 Handler
|
116 | rjmp nix;TIM1_CAPT ;Timer1 Capture Handler
|
117 | rjmp TIM1_COMPA ;Timer1 Compare A Handler
|
118 | rjmp nix;TIM1_COMPB ;Timer1 Compare B Handler
|
119 | rjmp nix;TIM1_OVF ;Timer1 Overflow Handler
|
120 | rjmp TIM0_OVF ;Timer0 Overflow Handler
|
121 | rjmp nix;SPI_STC ;SPI Transfer Complete Handler
|
122 | rjmp nix;USART_RXC ;USART RX Complete Handler
|
123 | rjmp nix;USART_UDRE ;UDR0 Empty Handler
|
124 | rjmp nix;USART_TXC ;USART TX Complete Handler
|
125 | rjmp nix;ANA_COMP ;Analog Comparator Handler
|
126 | rjmp nix;EXT_INT2 ;IRQ2 Handler
|
127 | rjmp nix;TIM0_COMP ;Timer0 Compare Handler
|
128 | rjmp nix;EE_RDY ;EEPROM Ready Handler
|
129 | rjmp nix;SPM_RDY ;Store Program memory Ready Handler
|
130 | nix: ;unbenutzte Interrupts
|
131 | reti ;zurück...
|
132 |
|
133 | .include"LCDprint.inc" ;LCD-Ausgabefunktionen
|
134 | .include"LCD_4x40.inc" ;LCD-Treiber-Routinen für LCDs mit M50530
|
135 |
|
136 |
|
137 |
|
138 | TIM0_OVF: ;Timer0 Overflow Handler
|
139 | in srsk,sreg ;SREG sichern
|
140 | sbr flags,1<<lcdtakt ;Timer0 Überlauf: LCD_Out freigeben
|
141 | out sreg,srsk ;SREG wiederherstellen
|
142 | reti ;
|
143 |
|
144 |
|
145 |
|
146 |
|
147 | reset:
|
148 | ldi wl,low(ramend) ;Stackpointer initialisieren
|
149 | out SPL,wl
|
150 | ldi wl,high(ramend)
|
151 | out SPH,wl
|
152 | clr null ;immer Null
|
153 | clr ff
|
154 | dec ff ;immer $ff
|
155 | clr tas ;definierten
|
156 | mov tz0,ff ;Startzustand
|
157 | clr tz1 ;für Tasten-Entprellung
|
158 | mov ztl,ff ;Zeit
|
159 | mov zth,ff ;auf -1
|
160 | ldi mp,16 ;Menüpunkt 16
|
161 | clr zeile ;Erster Eintrag
|
162 | clr maxzeile ;erstmal keine Einträge
|
163 |
|
164 | ldi wl,1<<se ;Sleep-Mode Idle aktivieren
|
165 | out mcucr,wl
|
166 |
|
167 | ldi wl,alltast ;Pull-Ups
|
168 | out tap+2,wl ;für Tasten einschalten
|
169 |
|
170 |
|
171 | sts xptr,null ;Pointer für LCD-Ringbuffer
|
172 | sts yptr,null ;setzen ($100...$1ff)
|
173 | ldi wl,1 ;Startwert
|
174 | mov lcw,wl ;LCD-Pausenzähler
|
175 |
|
176 | ldi wl,1<<acd ;Analog-Comparator aus
|
177 | out acsr,wl ;Strom sparen
|
178 |
|
179 | ldi wl,1<<cs10 ;Timer1 mit
|
180 | out tccr1b,wl ;Vorteiler 1:1 starten
|
181 | ldi wl,low(tim1zu) ;Interrupt-
|
182 | ldi wh,high(tim1zu) ;Intervall
|
183 | out ocr1ah,wh ;Timer1
|
184 | out ocr1al,wl ;setzen
|
185 |
|
186 |
|
187 |
|
188 |
|
189 | ldi wl,(1<<ocie1a)|(1<<toie0) ;|(1<<toie2)|(1<<ocie2) ;Int ein:
|
190 | out TIMSK,wl ;Timer1-Compare A (Zeit, 100ms),
|
191 | ;Timer0-Ovf (Zeichenausgabe LCD, variabel),
|
192 | ;Timer2-Ovf (Periodenende, Signal für Zündverteiler),
|
193 | ;Timer2-Comp. (Impulsende für Zündverteiler)
|
194 |
|
195 |
|
196 | clr flags ;alle Flags erstmal aus
|
197 | sei ;Interrupts freigeben
|
198 |
|
199 | rcall lcd_init ;Display initialisieren und löschen
|
200 | rjmp menu
|
201 |
|
202 | tastaus: ;Tasten puffer leeren und mainloop
|
203 | clr tfl ;Tastenflags löschen
|
204 | sbrc tfl,tli
|
205 | rjmp mainloop1 ;ja, keine Menüpunktausgabe...
|
206 |
|
207 | locate 1,11 ;debug...
|
208 | print8 mp
|
209 |
|
210 | cpi mp,17
|
211 | brcc tastaus1
|
212 | locate 0,0 ;Position der LCD-Ausgabe
|
213 | printt mt_head,mp ;Kopfzeile Menüpunkt ausgeben
|
214 | tastaus1:
|
215 | locate 7,0 ;Position der LCD-Ausgabe
|
216 | printt mt_key,mp ;Fußzeile Tastenzuordnung ausgeben
|
217 |
|
218 |
|
219 | mainloop1:
|
220 |
|
221 | andi tfl,alltast ;nur benutzte Tasten prüfen
|
222 |
|
223 | rjmp menu ;Tastendruck auswerten...
|
224 |
|
225 | numprint: ;Zeilennummer während Load ausgeben
|
226 | locate 3,10 ;Position
|
227 | print8 zeile ;Nummer ausgeben
|
228 | ret ;fertig...
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 | menu: ;Auswerten der Tasten
|
238 | mov wh,mp ;
|
239 | andi wh,15 ;Untermenüpunkte aktiv?
|
240 | brne untermenu ;ja...
|
241 | sbrc tfl,tre ;rechte Taste? nein...
|
242 | rjmp menurechts ;ja...
|
243 | sbrc tfl,tho ;obere Taste? nein...
|
244 | ldi mp,16 ;Menüebene 1
|
245 | sbrc tfl,tru ;untere Taste? nein...
|
246 | ldi mp,0 ;Menüebene 0
|
247 | cbr tfl,alltast ;alle Tasten sind erledigt
|
248 | rjmp menujump ;Menüpunkt aufrufen...
|
249 | untermenu:
|
250 | sbrc tfl,tre ;rechte Taste? nein...
|
251 | inc mp ;ja, +1
|
252 | sbrc tfl,tli ;linke Taste? nein...
|
253 | dec mp ;ja, -1
|
254 | cbr tfl,(1<<tre)|(1<<tli) ;Tasten links und rechts sind erledigt
|
255 | menujump: ;Menüpunktaufruf
|
256 | ldi zl,low(menujmp) ;Zeiger auf Sprungtabelle
|
257 | ldi zh,high(menujmp)
|
258 | add zl,mp ;Menüpunkt
|
259 | adc zh,null ;dazu
|
260 | ijmp ;Menüpunkt aufrufen
|
261 | menurechts:
|
262 | inc mp ;Menüpunkt um 1 hoch
|
263 | cbr tfl,alltast ;alle Tasten sind erledigt
|
264 | rjmp menujump ;weiter...
|
265 |
|
266 | menujmp: ;Menü-Sprungtabelle
|
267 | rjmp mp_00
|
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 | mp_00: ;Laden/Speichern
|
274 | sbrc tfl,tru ;Taste hoch? nein...
|
275 | dec zeile ;Zeile hoch
|
276 | sbrc tfl,tru ;Taste runter? nein...
|
277 | inc zeile ;Zeile runter
|
278 | sbrc tfl,tru ;Taste hoch? nein...
|
279 | dec zeile ;Zeile hoch
|
280 | sbrc tfl,tru ;Taste runter? nein...
|
281 | inc zeile ;Zeile runter
|
282 | sbrc tfl,tru ;Taste hoch? nein...
|
283 | dec zeile ;Zeile hoch
|
284 | sbrc tfl,tru ;Taste runter? nein...
|
285 | inc zeile ;Zeile runter
|
286 | sbrc tfl,tru ;Taste hoch? nein...
|
287 | dec zeile ;Zeile hoch
|
288 | sbrc tfl,tru ;Taste runter? nein...
|
289 | inc zeile ;Zeile runter
|
290 | sbrc tfl,tru ;Taste hoch? nein...
|
291 | dec zeile ;Zeile hoch
|
292 | sbrc tfl,tru ;Taste runter? nein...
|
293 | inc zeile ;Zeile runter
|
294 |
|
295 | cbr tfl,alltast ;Tastenpuffer leeren
|
296 | rjmp tastaus ;fertig...
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 | TIM1_COMPA: ;ISR Timer1-Interrupt (alle 10ms)
|
306 | in srsk,sreg ;SREG sichern (Exklusivregister)
|
307 | push xh ;benutzte Register
|
308 | push xl ;sichern
|
309 | in xl,ocr1al ;Weckzeit
|
310 | in xh,ocr1ah ;holen,
|
311 | subi xl,low(-tim1zu) ;Intervall
|
312 | sbci xh,high(-tim1zu) ;dazu,
|
313 | out ocr1ah,xh ;und wieder
|
314 | out ocr1al,xl ;in den Timer
|
315 | ;xl und xh können jetzt innerhalb dieser ISR frei benutzt werden
|
316 | Tastenabfrage: ;Entprellroutine geklaut bei Peter Dannegger...
|
317 | in xl,tap ;Tastenport einlesen (gedrückt=L)
|
318 | com xl ;invertieren (gedrückt=H)
|
319 | eor xl,tas ;nur Änderungen werden H
|
320 | and tz0,xl ;Prellzähler unveränderter Tasten löschen (Bit0)
|
321 | and tz1,xl ;Prellzähler unveränderter Tasten löschen (Bit1)
|
322 | com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0
|
323 | eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln
|
324 | and xl,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler
|
325 | and xl,tz1 ;beide Bits gesetzt sind (Zählerstand 3)
|
326 | eor tas,xl ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
|
327 | and xl,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten
|
328 | or tfl,xl ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
|
329 | ;in "tas" steht jetzt der gültige Tastenzustand,
|
330 | ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten...
|
331 | ;xl ist jetzt wieder frei für weitere temporäre Zwecke in der ISR
|
332 | inc teiler ;Sekundenvorteiler hoch
|
333 | brne nixvollsek ;nein...
|
334 | sbr flags,1<<neusek ;ja, Flag setzen,
|
335 | sbrs flags,aktiv ;ist Ablauf eingeschaltet? ja...
|
336 | rjmp nixvollsek ;nein...
|
337 | inc ztl ;Zeit erhöhen...
|
338 | brne nixvollsek ;Übertrag? nein...
|
339 | inc zth ;ja, erhöhen
|
340 | nixvollsek:
|
341 | tim1_ovf_ende:
|
342 | pop xl ;benutzte Register
|
343 | pop xh ;wiederherstellen
|
344 | out sreg,srsk ;SREG wiederherstellen
|
345 | reti ;fertig...
|
346 |
|
347 | mt_head: ;obere Menüzeilen (Menüpunkte)
|
348 | .dw menu000,menu010,menu020,menu030,menu040,menu050,menu060,menu070
|
349 | .dw menu080,menu090,menu100,menu110,menu120,menu130,menu030,menu030
|
350 | .dw menu160
|
351 |
|
352 | menu000: .db " ***MEN",$f5," MODUS *** ",0,0
|
353 | menu010: .db " KANAL WAEHLEN ",0
|
354 | menu020: .db " KANAL <1>",0
|
355 | menu030: .db " KANAL <2> ",0,0
|
356 | menu040: .db " KANAL <3> ",0,0
|
357 | menu050: .db " KANAL <4> ",0,0
|
358 | menu060: .db " KANAL <5> ",0,0
|
359 | menu070: .db " KANAL <6> ",0,0
|
360 | menu080: .db " KANAL <7> ",0,0
|
361 | menu090: .db " KANAL <8> ",0,0
|
362 | menu100: .db " STELLRICHTUNG",0,0
|
363 | menu110: .db " STELLRICHTUNG",0,0
|
364 | menu120: .db " KANAL <1> PLUS",0
|
365 | menu130: .db " KANAL <1> MINUS",0,0
|
366 |
|
367 | menu160: .db " ***************** ",0
|
368 |
|
369 | mt_key: ;untere Menüzeilen (Tastenzuordnung)
|
370 | .dw m007,m017,m027,m037,m047,m057,m067,m077
|
371 | .dw m087,m097,m107,m117,m127,m137,m037,leerz
|
372 | .dw m167,m177,m187,m197,m197,m177a,m177a,m177a
|
373 | .dw m167,m197,m197
|
374 |
|
375 |
|
376 |
|
377 | m007: .db " BITTE WEITER >",0
|
378 | m017: .db "<---- ENTER >",0
|
379 | m027: .db "<---- ENTER >",0
|
380 | m037: .db "<---- ENTER >",0
|
381 | m047: .db "<---- ENTER >",0
|
382 | m057: .db "<---- ENTER >",0
|
383 | m067: .db "<---- ENTER >",0
|
384 | m077: .db "<---- ENTER >",0
|
385 | m087: .db "<---- ENTER >",0
|
386 | m097: .db "<---- ENTER >",0
|
387 | m107: .db "<---- PLUS >",0
|
388 | m117: .db "<---- ENTER >",0
|
389 | m127: .db "<---- MINUS >",0
|
390 | m137: .db "<---- ENTER >",0
|
391 |
|
392 | m167: .db " MEN",$f5," 1>",0,0
|
393 | m177: .db " MEN",$f5," 2>",0,0
|
394 | m177a: .db " MEN",$f5," 3>",0,0
|
395 | m187: .db " MEN",$f5," 4>",0,0
|
396 | m197: .db " MEN",$f5," 5>",0,0
|
397 |
|
398 | leerz: .db " ",0,0
|