1 | ;Demoprogramm für 8-fach-PWM mit Tastensteuerung und Pollin-LCD 4x27.
|
2 |
|
3 | ;8 LEDs gegen Vcc an Port B (STK500)
|
4 | ;4 entprellte Tasten gegen GND für die einzelnen PWM-Kanäle an Port C
|
5 | ;Davon 2 Tasten (Dimm-Tasten) mit Repeat-Funktion bei Dauerdruck.
|
6 | ;LCD 4x27 an Port D
|
7 |
|
8 | .nolist ;List der Include-Datei unterdrücken
|
9 | .include "m8515def.inc" ;vereinbarte Namen verwenden (lt. Datasheet)
|
10 | .list ;Programm listen
|
11 | .listmac ;Makros listen
|
12 | .equ clock = 8000000 ;Taktfrequenz 8Mhz
|
13 |
|
14 |
|
15 |
|
16 | .equ teilfaktor=100 ;Zählumfang des Teilers
|
17 |
|
18 | .equ pwu = 100 ;PWM-Zählumfang (sollte 100 sein wegen %)
|
19 | .equ timerwert = -100 ;Timer-Startwert (Reload)-100
|
20 | .equ step=1 ;Schrittweite für Änderung pro Tastendruck
|
21 | .equ lep=portb ;Port für LEDs
|
22 | .equ tap=pinc ;Tastenport
|
23 | .equ save = 5 ;Taste zum Speichern im EEP
|
24 | .equ load = 4 ;Taste zu, Lesen aus EEP
|
25 | .equ dimplus = 3 ;Taste Dimmen plus
|
26 | .equ dimminus = 2 ;Taste Dimmen minus
|
27 | .equ chanplus = 1 ;Taste Kanal hoch
|
28 | .equ chanminus = 0 ;Taste Kanal runter
|
29 | .equ dimtast=(1<<dimplus)|(1<<dimminus)|(1<<load)|(1<<save) ;Maske auf
|
30 | ;.equ alltast=dimtast|(1<<chanplus)|(1<<chanminus)|(1<<ruck)
|
31 | .equ alltast=255
|
32 |
|
33 | .equ twz0=250 ;Startwert Tastendruckdauer
|
34 | .equ twz1=30 ;Wiederholwert für Tasten
|
35 |
|
36 |
|
37 | .equ lcdHintergrundstromport=portE ;Port LCD HINTERGRUND BELEUCHTUNG
|
38 | .equ lcdHintergrundstrompin=1 ;Pin Stromversorgung LCD HINTERGRUND BELEUCHTUNG
|
39 |
|
40 | .dseg ;SRAM-Variablen
|
41 | sekunde: .byte 1 ;aktuelle Sekunde
|
42 | minute: .byte 1 ;aktuelle Minute
|
43 | stunde: .byte 1
|
44 |
|
45 | ;Array mit 8 Sollwerten in Registern, damit die Software-PWM schnell wird
|
46 | .def soll0 = r0 ;Sollwert Kanal 1
|
47 | .def soll1 = r1 ;Sollwert Kanal 2
|
48 | .def soll2 = r2 ;Sollwert Kanal 3
|
49 | .def soll3 = r3 ;Sollwert Kanal 4
|
50 | .def soll4 = r4 ;Sollwert Kanal 5
|
51 | .def soll5 = r5 ;Sollwert Kanal 6
|
52 | .def soll6 = r6 ;Sollwert Kanal 7
|
53 | .def soll7 = r7 ;Sollwert Kanal 8
|
54 |
|
55 | .def tsw = r8 ;Timer-Startwert
|
56 | .def sregtemp = r9 ;Sicherheitskopie SREG
|
57 |
|
58 | .def tz0 = r11 ;Tasten-Prellzähler Bit0
|
59 | .def tz1 = r12 ;Tasten-Prellzähler Bit1
|
60 | .def tas = r13 ;Tastenstatus (gültig)
|
61 | .def null = r14 ;immer 0
|
62 | .def kanal = r15 ;aktuelle Kanalnummer
|
63 |
|
64 | .def temp = r16 ;temporär (exklusiv in der ISR)
|
65 | .def tfl = r17 ;Flags für Tasten, die gedrückt wurden
|
66 | .def twz=r18 ;Tasten-Wiederholzähler
|
67 |
|
68 |
|
69 | .def teiler=r19 ;Teiler für Timer (1 Sekunde)
|
70 |
|
71 |
|
72 | .def pwz = r22 ;PWM-Zähler
|
73 | .def flags = r23 ;Steuerflags
|
74 | .equ neusek=0 ;neue Sekunde
|
75 | .equ neuhalb=1 ;neue halbe Sekunde
|
76 | .equ hundertstel=2 ;neue Hundertstel Sekunde
|
77 | .equ uhraktiv=3 ;Flag für Uhrzeitausgabe
|
78 | ;.equ uhrhalt=4 ;Flag für angehaltene Uhr
|
79 |
|
80 |
|
81 | .equ lcdcontroller1 = 4 ;Flag für Controller 1
|
82 | .equ lcdcontroller2 = 6 ;Flag für Controller 2
|
83 |
|
84 | .def wl=r24 ;Working L
|
85 | .def wh=r25 ;Working H
|
86 |
|
87 |
|
88 | .cseg
|
89 | .org 0 ;Reset- und Interrupt-Vektoren AT-Mega 8515
|
90 | rjmp RESET ;Reset Handler
|
91 | rjmp nix;EXT_INT0 ;IRQ0 Handler
|
92 | rjmp nix;EXT_INT1 ;IRQ1 Handler
|
93 | rjmp nix;TIM1_CAPT ;Timer1 Capture Handler
|
94 | rjmp nix;TIM1_COMPA ;Timer1 Compare A Handler
|
95 | rjmp nix;TIM1_COMPB ;Timer1 Compare B Handler
|
96 | rjmp nix;TIM1_OVF ;Timer1 Overflow Handler
|
97 | rjmp TIM0_OVF ;Timer0 Overflow Handler
|
98 | rjmp nix;SPI_STC ;SPI Transfer Complete Handler
|
99 | rjmp nix;USART_RXC ;USART RX Complete Handler
|
100 | rjmp nix;USART_UDRE ;UDR0 Empty Handler
|
101 | rjmp nix;USART_TXC ;USART TX Complete Handler
|
102 | rjmp nix;ANA_COMP ;Analog Comparator Handler
|
103 | rjmp nix;EXT_INT2 ;IRQ2 Handler
|
104 | rjmp nix;TIM0_COMP ;Timer0 Compare Handler
|
105 | rjmp nix;EE_RDY ;EEPROM Ready Handler
|
106 | rjmp nix;SPM_RDY ;Store Program memory Ready Handler
|
107 | nix: ;unbenutzte Interrupts
|
108 | rjmp nix
|
109 | reti ;zurück...
|
110 |
|
111 |
|
112 | .include"LCD_4x27.inc" ;LCD-Routinen für 4-Zeilen-LCDs mit HD44780
|
113 |
|
114 | ;Da nur wenige LCD Ausgabefunktionen benötigt werden, wurde auf das Einbinden
|
115 | ;der Ausgaberoutinensammlung verzichtet und die beiden benötigten Routinen
|
116 | ;und deren Macros hier heschrieben. Auf Registersicherung wurde verzichtet,
|
117 | ;da die Ausgabe nur in der Initialisierung bzw. der Mainloop erfolgt.
|
118 | ;Die 8-Bit-Ausgaberoutine wurde so verändert, dass die Zahl immer drei
|
119 | ;Ausgabepositionen belegt, also eine feste Breite hat, Ist die erste Ziffer
|
120 | ;eine 0, so wird sie als Leerzeichen ausgegeben. Damit ist die Anzeige von
|
121 | ;00% bis 100% möglich, ohne dass die Ausgabeposition flattert.
|
122 |
|
123 | .macro print83 ;Reg.
|
124 | mov xl,@0 ;Quellregister kopieren
|
125 | rcall lcd_print83 ;Routine aufrufen
|
126 | .endmacro
|
127 |
|
128 |
|
129 | .macro printf ;Startadresse des Strings im Flash als Label
|
130 | ;Gibt einen String aus dem Flash an LCD aus
|
131 | ;Ein Parameter beschreibt die Startadresse, das Ende ist $00
|
132 | ldi zh,high(2*@0) ;Pointer
|
133 | ldi zl,low(2*@0) ;setzen
|
134 | rcall lcd_printf ;Aufruf...
|
135 | .endmacro
|
136 |
|
137 |
|
138 | lcd_print83: ;gibt Wert in XL dreistellig aus (mit Führungsleerzeichen)
|
139 | ldi wl,-1+'0' ;Hunderter-Stelle als ASCII-Zeichen, Zahl ist pos.
|
140 | inc wl ;Hunderter hoch und
|
141 | subi xl,100 ;100 subtrahieren bis zum Unterlauf
|
142 | brsh pc-2 ;Unterlauf? nein, 2 Zeilen hoch
|
143 | cpi wl,'0' ;ja, ist Ziffer = "0"?
|
144 | brne pc+2 ;nein, nicht verändern...
|
145 | ldi wl,' ' ;ja, durch Leerzeichen ersetzen
|
146 | rcall lcd_data ;Hunderter ausgeben...
|
147 | ldi wl,10+'0' ;Zehner-Stelle als ASCII-Zeichen, Zahl ist neg.
|
148 | dec wl ;Zehner runter und
|
149 | subi xl,-10 ;10 addieren bis zum Überlauf
|
150 | brlo pc-2 ;Überlauf? nein, 2 Zeilen hoch...
|
151 | rcall lcd_data ;ja, Zehner Stelle ausgeben...
|
152 | ldi wl,'0' ;ASCII-0
|
153 | add wl,xl ;Einer addieren (Rest war ja positiv)
|
154 | rcall lcd_data ;Einer ausgeben...
|
155 | ret ;zurück
|
156 |
|
157 |
|
158 | lcd_printf: ;Wird vom Makro aufgerufen. Gibt Flash-String an LCD aus.
|
159 | push wl
|
160 | lpm wl,z+ ;Zeichen holen
|
161 | tst wl ;Ende-Kennung?
|
162 | breq pc+3 ;ja...
|
163 | rcall lcd_data ;nein, ausgeben
|
164 | rjmp pc-4 ;nochmal
|
165 | pop wl
|
166 | ret
|
167 |
|
168 | ;----------------------------------------------------------------------------
|
169 |
|
170 | reset:
|
171 | ;Stackpointer initialisieren:
|
172 | ldi wl,low(ramend)
|
173 | out SPL,wl
|
174 | ldi wl,high(ramend)
|
175 | out SPH,wl
|
176 | ;PWM-Ausgänge (LEDs) initialisieren:
|
177 | ldi wl, 0xff ;Port für LEDs (PWM-Ausgänge)
|
178 | out lep-1,wl ;= Ausgang (DDRx=PORTx-1)
|
179 | ;Tasten-Eingänge initialisieren:
|
180 | ldi wl, alltast ;pull-ups für Tasten
|
181 | out tap+2,wl ;einschalten (PORTx=PINx+2)
|
182 | ;Die Initialisierung der LCD-Ports erfolgt in der LCD-Include-Datei!!!
|
183 |
|
184 |
|
185 |
|
186 | ldi temp, 0xFF ;Port E = Ausgang
|
187 | out DDRE, temp
|
188 |
|
189 | ldi flags,1<<uhraktiv ;Uhrzeitanzeige einschalten
|
190 |
|
191 | ;alle 8 PWMs erstmal auf 0
|
192 | ; clr soll0
|
193 | ; clr soll1
|
194 | ; clr soll2
|
195 | ; clr soll3
|
196 | ; clr soll4
|
197 | ; clr soll5
|
198 | ; clr soll6
|
199 | ; clr soll7
|
200 |
|
201 | clr null ;immer 0
|
202 | clr tz0 ;Definierte Startbedingung
|
203 | clr tz1 ;für Tastenentprellung
|
204 | clr tas
|
205 | clr tfl
|
206 | clr twz
|
207 | clr kanal ;mit Kanal 1 (0) beginnen
|
208 |
|
209 |
|
210 | ; ldi wl,12 ;
|
211 | ; sts stunde,wl ;Stunde
|
212 | ; ldi wl,0
|
213 | ; sts minute,wl ;Minute
|
214 | ; ldi wl,0
|
215 | ; sts sekunde,wl ;Sekunde
|
216 |
|
217 |
|
218 |
|
219 | ;Initialisierung Timer0
|
220 | ldi wl,1 ;1 ;Vorteiler 1:1
|
221 | out tccr0,wl ;für Timer0
|
222 | ldi wl,1<<toie0 ;Überlauf-Interrupt
|
223 | out timsk,wl ;für Timer0 freigeben
|
224 | ldi wl,timerwert+12 ;Timer-Startwert, korregiert mit Int-Aufruf12
|
225 | mov tsw,wl ;definieren
|
226 | out tcnt0,tsw ;und ausgeben
|
227 | sei ;Interrupts global freigeben
|
228 | rcall lcd_init ;LCD initialisieren
|
229 |
|
230 | ;Start-Parameter aus EEP holen:
|
231 | out eearh,null ;untere Page
|
232 | out eearl,kanal ;Adresse/Kanal 0
|
233 | sbi eecr,eere ;Leseimpuls generieren
|
234 | in soll0,eedr ;Wert einlesen
|
235 | inc kanal ;nächster Kanal
|
236 | out eearl,kanal ;Adresse/Kanal 1
|
237 | sbi eecr,eere ;Leseimpuls generieren
|
238 | in soll1,eedr ;Wert einlesen
|
239 | inc kanal ;nächster Kanal
|
240 | out eearl,kanal ;Adresse/Kanal 2
|
241 | sbi eecr,eere ;Leseimpuls generieren
|
242 | in soll2,eedr ;Wert einlesen
|
243 | inc kanal ;nächster Kanal
|
244 | out eearl,kanal ;Adresse/Kanal 3
|
245 | sbi eecr,eere ;Leseimpuls generieren
|
246 | in soll3,eedr ;Wert einlesen
|
247 | inc kanal ;nächster Kanal
|
248 | out eearl,kanal ;Adresse/Kanal 4
|
249 | sbi eecr,eere ;Leseimpuls generieren
|
250 | in soll4,eedr ;Wert einlesen
|
251 | inc kanal ;nächster Kanal
|
252 | out eearl,kanal ;Adresse/Kanal 5
|
253 | sbi eecr,eere ;Leseimpuls generieren
|
254 | in soll5,eedr ;Wert einlesen
|
255 | inc kanal ;nächster Kanal
|
256 | out eearl,kanal ;Adresse/Kanal 6
|
257 | sbi eecr,eere ;Leseimpuls generieren
|
258 | in soll6,eedr ;Wert einlesen
|
259 | inc kanal ;nächster Kanal
|
260 | out eearl,kanal ;Adresse/Kanal 7
|
261 | sbi eecr,eere ;Leseimpuls generieren
|
262 | in soll7,eedr ;Wert einlesen
|
263 | clr kanal ;wieder Kanal 0
|
264 |
|
265 |
|
266 | ;Ende der Initialisierung, Programm 'fällt' jetzt in die Hauptschleife
|
267 |
|
268 | locate 0,0 ;feststehenden Text Zeile 0
|
269 | printf txt_zeile0 ;ausgeben
|
270 | locate 1,0 ;feststehenden Text Zeile 1
|
271 | printf txt_zeile1 ;ausgeben
|
272 | locate 2,0 ;feststehenden Text Zeile 2
|
273 | printf txt_zeile2 ;ausgeben
|
274 | locate 3,0 ;feststehenden Text Zeile 3
|
275 | printf txt_zeile3 ;ausgeben
|
276 |
|
277 | sbi lcdHintergrundstromport,lcdHintergrundstrompin ;erstmal lcdHintergrundstromport
|
278 | sbi lcdHintergrundstromport-1,lcdHintergrundstrompin ;einschalten
|
279 | mainloop: ;Hauptschleife, Endlosschleife
|
280 | ;hier passiert:
|
281 | ;- LCD-Ausgabe,
|
282 | ;- Abfrage von Ereignissen und Reaktion darauf
|
283 |
|
284 |
|
285 | sbrc flags,neusek ;neue Sekunde da?? nein...
|
286 | rjmp neusekunde ;ja...
|
287 | ; sbrc flags,neuhalb ;neue halbe Sekunde da?? nein...
|
288 | ; rjmp halbsekunde ;ja...
|
289 |
|
290 |
|
291 |
|
292 | locate 0,0+8 ;Ausgabeposition Sollwert
|
293 | print83 soll0 ;Sollwert ausgeben
|
294 |
|
295 | locate 1,0+8 ;Ausgabeposition Sollwert
|
296 | print83 soll1 ;Sollwert ausgeben
|
297 |
|
298 | locate 2,0+8 ;Ausgabeposition Sollwert
|
299 | print83 soll2 ;Sollwert ausgeben
|
300 |
|
301 | locate 3,0+8 ;Ausgabeposition Sollwert
|
302 | print83 soll3 ;Sollwert ausgeben
|
303 |
|
304 | .equ rsp=15 ;Position rechte Spalte
|
305 |
|
306 | locate 0,rsp+8 ;Ausgabeposition Sollwert
|
307 | print83 soll4 ;Sollwert ausgeben
|
308 |
|
309 | locate 1,rsp+8 ;Ausgabeposition Sollwert
|
310 | print83 soll5 ;Sollwert ausgeben
|
311 |
|
312 | locate 2,rsp+8 ;Ausgabeposition Sollwert
|
313 | print83 soll6 ;Sollwert ausgeben
|
314 |
|
315 | locate 3,rsp+8 ;Ausgabeposition Sollwert
|
316 | print83 soll7 ;Sollwert ausgeben
|
317 | rcall tasten ;eventuelle Tastendrücke abarbeiten
|
318 |
|
319 | locate 1,13 ;Position Mitte zweite Zeile
|
320 | ldi wl,'1' ;Kanalnummer
|
321 | add wl,kanal ;zur Ziffer wandeln
|
322 | rcall lcd_data ;und ausgeben...
|
323 |
|
324 | rjmp mainloop ;fertig, Endlosschleife...
|
325 |
|
326 | tasten: ;UP, fragt entprellte Tasten ab
|
327 | ;zuerst die Kanaltasten:
|
328 | sbrc tfl,chanplus RCALL DISPLAYON ;Kanal-Plus-Taste betätigt? - nein...
|
329 | inc kanal ;ja, Kanalnummer erhöhen
|
330 |
|
331 | sbrc tfl,chanminus RCALL DISPLAYON ;Kanal-Minus-Taste betätigt? - nein...
|
332 | dec kanal ;ja, Kanalnummer vermindern
|
333 | ldi wl,7 ;Wertebereich (Zählumfang) auf
|
334 | and kanal,wl ;0..7 begrenzen (untere 3 Bits maskieren)
|
335 |
|
336 | ;Kopie des PWM-Wertes des aktuellen Kanals nach WL holen
|
337 | ;(wird für dimm und EEP gebraucht):
|
338 | clr zh ;Pointer auf Sollwert des aktuellen
|
339 | mov zl,kanal ;Kanals (Kanal als Index auf Array)
|
340 | ld wl,z ;Kopie des PWM-Wertes des akt. Kanals holen
|
341 |
|
342 | eep_ready: ;warten, falls EEP noch beschäftigt ist
|
343 | sbic eecr,eewe ;ist der EEP noch beschäftigt? - nein...
|
344 | rjmp eep_ready ;ja, warten, nochmal prüfen...
|
345 |
|
346 | ;EEP-Adresse auf Kanalnummer setzen:
|
347 | out eearh,null ;immer untere Page benutzen
|
348 | out eearl,kanal ;Adresse auf Kanalnummer
|
349 | ;aktuellen PWM-Wert ins EEP legen, falls geschrieben werden soll:
|
350 | out eedr,wl ;ausgewählter PWM-Wert ins EEP
|
351 |
|
352 | sbrc tfl, save ;Save-Taste betätigt? - nein...
|
353 | rcall eep_write ;ja, abarbeiten
|
354 | sbrc tfl, load ;Ladetaste betätigt? - nein...
|
355 | rcall eep_read ;ja, abarbeiten
|
356 |
|
357 | ;jetzt die Dimmtasten prüfen:
|
358 | andi tfl,dimtast ;alle Tasten außer den Dimmtasten rücksetzen
|
359 | brne dimm ;war eine Dimmtaste betätigt? - ja...
|
360 | tasten_e: ;Ende des UP
|
361 | st z,wl ;Sollwert ins Array zurückschreiben
|
362 | ret ;nein, zurück...
|
363 |
|
364 | dimm: ;ändert Sollwert des aktiven Kanals
|
365 | sbrs tfl,dimplus ;Taste Dimm+? - ja...
|
366 | rjmp dimm1 ;nein, weiter...
|
367 | ;Dimplus-Taste wurde betätigt
|
368 | subi wl,-step ;ja, Sollwert vergrößern
|
369 | cpi wl,pwu ;PWM-Zählumfang überschritten?
|
370 | brcs dimm1 ;nein...
|
371 | ldi wl,pwu ;ja, auf PWM-Zählumfang begrenzen
|
372 | dimm1:
|
373 | sbrs tfl,dimminus ;Taste Dimm-? - ja...
|
374 | rjmp dimm2 ;nein, weiter...
|
375 | ;Dimminus-Taste wurde betätigt
|
376 | subi wl,step ;ja, Sollwert vermindern
|
377 | brcc dimm2 ;Unterlauf? nein...
|
378 | clr wl ;ja, auf 0 setzen
|
379 | dimm2:
|
380 | cbr tfl,dimtast ;Dimmtasten zurücksetzen (Job ist ja erledigt)
|
381 | rjmp tasten_e ;fertig...
|
382 |
|
383 |
|
384 | eep_read: ;EEP-Datensatz lesen, Adresse ist bereits gesetzt
|
385 | ;sbi eece,eere ;Leseimpuls generieren
|
386 | ;in wl,eedr ;gelesenes Datenbyte nach wl, um es über den Z-Pointer
|
387 | ; Wait for completion of previous write
|
388 | sbic EECR,EEWE
|
389 | rjmp eep_read
|
390 | ; Set up address (r18:r17) in address register
|
391 | out EEARH, NULL
|
392 | out EEARL, KANAL
|
393 | ; Start eeprom read by writing EERE
|
394 | sbi EECR,EERE
|
395 | ; Read data from data register
|
396 | in WL,EEDR ;ins Array mit den Sollwerten zurück zu schreiben
|
397 | ret ;fertig und zurück...
|
398 |
|
399 |
|
400 | eep_write: ;EEP schreiben, Adresse und Daten sind bereits gesetzt
|
401 | cli ;Interrupts sperren, damit das EEP-Timing
|
402 | ; Wait for completion of previous write
|
403 | sbic EECR,EEWE
|
404 | rjmp eep_write
|
405 | ; Set up address (r18:r17) in address register
|
406 | out EEARH, NULL ; R0
|
407 | out EEARL, KANAL
|
408 | ; Write data (r16) to data register
|
409 | out EEDR,WL
|
410 |
|
411 | ; Write logical one to EEMWE
|
412 | sbi EECR,EEMWE
|
413 | ; Start eeprom write by setting EEWE
|
414 | sbi EECR,EEWE ;nicht gestört wird
|
415 | ;sbi eecr,eemwe ;Schreibschutz (für 4 Takte) aufheben
|
416 | ;sbi eecr,eewe ;Schreibimpuls generieren
|
417 | sei ;Interrupts wieder erlauben
|
418 | ret ;fertig und zurück...
|
419 |
|
420 |
|
421 |
|
422 | ;***********************************************************************
|
423 |
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 |
|
434 |
|
435 | Tim0_OVF: ;ISR Timer0-Überlauf
|
436 | in sregtemp, sreg ;Sreg sichern
|
437 | out tcnt0,tsw ;Timer auf Startwert setzen
|
438 | inc pwz ;PWM-Treppenzähler erhöhen
|
439 | cpi pwz, pwu ;PWM-Zählumfang erreicht?
|
440 | brne Time0_a ;nein... (die 3 Punkte bedeuten bei mir Sprung)
|
441 | ;hier landet das Programm nur bei jeder hundertsten Runde
|
442 | clr pwz ;ja, von vorn zählen und Tasten abfragen
|
443 | Tastenabfrage: ;Entprellroutine (Algorithmus geklaut bei Peter Dannegger...)
|
444 | in temp,tap ;Tastenport einlesen (gedrückt=L)
|
445 | com temp ;invertieren (gedrückt=H)
|
446 | eor temp,tas ;nur Änderungen werden H
|
447 | and tz0,temp ;Prellzähler unveränderter Tasten löschen (Bit0)
|
448 | and tz1,temp ;Prellzähler unveränderter Tasten löschen (Bit1)
|
449 | com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0
|
450 | eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln
|
451 | and temp,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler
|
452 | and temp,tz1 ;beide Bits gesetzt sind (Zählerstand 3)
|
453 | eor tas,temp ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
|
454 | and temp,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten
|
455 | or tfl,temp ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
|
456 | ;tmp ist wieder frei, tas enthält den entprellten Tastenstatus,
|
457 | ;tfl die neu gerückten Tasten
|
458 | Tastendauer:
|
459 | mov temp,tas ;Tastenzustand kopieren
|
460 | andi temp,dimtast ;nur Dimm-Tasten mit Wiederholfunktion stehen lassen
|
461 | tst temp ;ist eine Taste betätigt?
|
462 | breq Tastendauer0 ;nein, Dauer auf Startwert...
|
463 | dec twz ;ja, Zähler runter
|
464 | brne Tastenabfrage_e ;Dauer abgelaufen? - nein...
|
465 | or tfl,temp ;ja, noch aktive Tasten übernehmen
|
466 | ldi twz,twz1 ;und Zähler auf Wiederholwert setzen
|
467 | Tastenabfrage_e:
|
468 | ;in "tfl" stehen jetzt wieder die Flags der länger betätigten Tasten
|
469 | ;sie werden nach Abarbeitung gelöscht
|
470 |
|
471 | ;*************************************************************
|
472 | sbr flags,1<<hundertstel ;neue hundertstel Sekunde
|
473 | inc teiler ;Sekundenvorteiler hoch
|
474 | cpi teiler,teilfaktor ;Endwert erreicht?
|
475 | brne nixvollsek ;nein...
|
476 | sbr flags,1<<neusek ;ja, Flag setzen,
|
477 | clr teiler ;und Teiler löschen
|
478 |
|
479 |
|
480 |
|
481 | nixvollsek:
|
482 | cpi teiler,teilfaktor /1.5 ;2 ;Halbe Sekunde?
|
483 | brne Time0_a ;nein...
|
484 | sbr flags,1<<neuhalb ;ja, Flag setzen
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 | Time0_a: ;Vergleich der einzelnen PWM-Werte mit dem PWM-Treppenzähler
|
491 | ;(Idee geklaut bei Peter Dannegger)
|
492 | cp pwz, soll7 ;Sollwert erreicht? (Ergebnis im Carry)
|
493 | rol temp ;Carry-Bits "einsammeln", dieses wird bis Bit7 durchgeschoben
|
494 | cp pwz, soll6
|
495 | rol temp ;Bit 6
|
496 | cp pwz, soll5
|
497 | rol temp ;Bit 5
|
498 | cp pwz, soll4
|
499 | rol temp ;Bit 4
|
500 | cp pwz, soll3
|
501 | rol temp ;Bit 3
|
502 | cp pwz, soll2
|
503 | rol temp ;Bit 2
|
504 | cp pwz, soll1
|
505 | rol temp ;Bit 1
|
506 | cp pwz, soll0
|
507 | rol temp ;Bit 0
|
508 | com temp ;invertieren da low-aktive LED im STK500
|
509 | out lep, temp ;Ausgabe
|
510 | out sreg, sregtemp ;Sreg wiederherstellen
|
511 | reti ;ISR fertig...
|
512 |
|
513 | Tastendauer0: ;Reset Dauerzähler
|
514 | ldi twz,twz0 ;Tastendauerzähler auf Startwert
|
515 | rjmp Tastenabfrage_e ;fertig...
|
516 |
|
517 |
|
518 | neusekunde: ;neue Sekunde addieren (Job der Mainloop)
|
519 | cbr flags,1<<neusek ;Flag löschen (Job ist in Arbeit...)
|
520 |
|
521 |
|
522 |
|
523 | lds wh,sekunde ;Sekunde aus SRAM holen
|
524 | inc wh ;erhöhen
|
525 | sts sekunde,wh ;erstmal zurück ins SRAM
|
526 | cpi wh,60 ;Überlauf?
|
527 | brlo ausgabe ;nein...
|
528 | clr wh ;ja, von 0 beginnen
|
529 | sts sekunde,wh ;Korrektur zurück ins SRAM
|
530 |
|
531 | lds wh,minute ;Minute aus SRAM holen
|
532 | inc wh ;erhöhen
|
533 | sts minute,wh ;erstmal zurück ins SRAM
|
534 | cpi wh,5 ;Überlauf?
|
535 | brlo ausgabe ;nein...
|
536 | clr wh ;ja, von 0 beginnen
|
537 |
|
538 | cbi lcdHintergrundstromport,lcdHintergrundstrompin ;lcdHintergrund ausschalten nach ca.5 minuten
|
539 | sts minute,wh ;Korrektur zurück ins SRAM
|
540 |
|
541 |
|
542 |
|
543 | lds wh,stunde ;Sekunde aus SRAM holen
|
544 | inc wh ;erhöhen
|
545 | sts stunde,wh ;erstmal zurück ins SRAM
|
546 | cpi wh,24 ;Überlauf?
|
547 | brlo ausgabe ;nein...
|
548 | clr wh ;ja, von 0 beginnen
|
549 | sts stunde,wh ;Korrektur zurück ins SRAM
|
550 |
|
551 |
|
552 | ausgabe: ;Wochentag und Uhrzeit ausgeben
|
553 |
|
554 |
|
555 | RJMP MAINLOOP
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 |
|
562 | DISPLAYON:
|
563 | sbi lcdHintergrundstromport,lcdHintergrundstrompin ;lcdHintergrundstromport
|
564 | sbi lcdHintergrundstromport-1,lcdHintergrundstrompin ; nach tastendruck wieder einschalten
|
565 |
|
566 |
|
567 | RET
|
568 |
|
569 |
|
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 | txt_zeile0: .db "Kanal 1 % Kanal 5 %",0
|
580 | txt_zeile1: .db "Kanal 2 % Kanal 6 %",0
|
581 | txt_zeile2: .db "Kanal 3 % Kanal 7 %",0
|
582 | txt_zeile3: .db "Kanal 4 % Kanal 8 %",0
|
583 |
|
584 | .ESEG
|
585 | .db 10,100,23,30,45,55,78,90
|