1 | ;Demoprogramm für 8-fach-PWM mit Tastensteuerung Up-Down.
|
2 |
|
3 | ;8 LEDs gegen Vcc an PortB (STK500)
|
4 | ;8 entprellte Tasten gegen GND für die einzelnen PWM-Kanäle an PortD
|
5 | ;1 "Shift-Taste" an PA6 gegen GND zum Wählen der Stellrichtung der Kanaltasten.
|
6 | ;Shift offen -> Kanaltasten zählen hoch,
|
7 | ;Shift betätigt -> Kanaltasten zählen runter.
|
8 | ;Der Zählumfang wird nach oben und unten begrenzt.
|
9 |
|
10 | .include "8515def.inc"
|
11 |
|
12 | .equ pwu = 100 ;PWM-Zählumfang
|
13 | .equ timerwert = -100 ;Timer-Startwert (Reload)
|
14 | .equ step=5 ;Schrittweite für Änderung pro Tastendruck
|
15 | .equ lep=portb ;Port für LEDs
|
16 | .equ tap=pind ;Tastenport
|
17 | .equ ship=pina ;Port für Shift-Taste
|
18 | .equ shib=6 ;Bit für Shift-Taste
|
19 |
|
20 | .def soll0 = r0 ;Sollwert Kanal 1
|
21 | .def soll1 = r1 ;Sollwert Kanal 2
|
22 | .def soll2 = r2 ;Sollwert Kanal 3
|
23 | .def soll3 = r3 ;Sollwert Kanal 4
|
24 | .def soll4 = r4 ;Sollwert Kanal 5
|
25 | .def soll5 = r5 ;Sollwert Kanal 6
|
26 | .def soll6 = r6 ;Sollwert Kanal 7
|
27 | .def soll7 = r7 ;Sollwert Kanal 8
|
28 | .def tsw = r8 ;Timer-Startwert
|
29 | .def sregtemp = r9 ;Sicherheitskopie SREG
|
30 | .def scan=r10 ;Scannwert Tastenport
|
31 | .def tz0=r11 ;Tasten-Prellzähler Bit0
|
32 | .def tz1=r12 ;Tasten-Prellzähler Bit1
|
33 | .def tas=r13 ;Tastenstatus (gültig)
|
34 |
|
35 | .def temp = r16
|
36 | .def tfl=r17 ;Flags für Tasten, die gedrückt wurden
|
37 | .def pwz = r18 ;PWM-Zähler
|
38 | .def task=r19 ;Taskscheibe für diverse Aufgaben
|
39 | .def ri=r20 ;Richtung der Änderung
|
40 | .def max=r21 ;Maximum
|
41 |
|
42 |
|
43 | .cseg
|
44 | .org 0 ;Reset- und Interrupt-Vektoren 8535
|
45 | rjmp RESET ;Reset Handler
|
46 | reti; rjmp EXT_INT0 ;IRQ0 Handler
|
47 | reti; rjmp EXT_INT1 ;IRQ1 Handler
|
48 | reti; rjmp TIM1_CAPT ;Timer1 Capture Handler
|
49 | reti; rjmp TIM1_COMPA ;Timer1 CompareA Handler
|
50 | reti; rjmp TIM1_COMPB ;Timer1 CompareB Handler
|
51 | reti; rjmp TIM1_OVF ;Timer1 Overflow Handler
|
52 | rjmp TIM0_OVF ;Timer0 Overflow Handler
|
53 | reti; rjmp SPI_STC; ;SPI Transfer Complete Handler
|
54 | reti; rjmp UART_RXC ;UART RX Complete Handler
|
55 | reti; rjmp UART_DRE ;UDR Data-Reg Empty Handler
|
56 | reti; rjmp UART_TXC ;UART TX Complete Handler
|
57 | reti; rjmp ANA_COMP ;Analog Comparator Handler
|
58 |
|
59 | Reset:
|
60 |
|
61 | ldi temp, high(ramend)
|
62 | out sph, temp
|
63 | ldi temp, low (ramend)
|
64 | out spl, temp ;Stack initialisiert
|
65 |
|
66 | clr soll0
|
67 | clr soll1
|
68 | clr soll2
|
69 | clr soll3
|
70 | clr soll4
|
71 | clr soll5
|
72 | clr soll6
|
73 | clr soll7
|
74 | clr tz0 ;Definierte Startbedingung
|
75 | clr tz1 ;für Tastenentprellung
|
76 | clr tas
|
77 | clr tfl
|
78 |
|
79 | ldi temp, 0xff
|
80 | out lep-1,temp ;Ports B = Ausgang (DDRx=PORTx-1)
|
81 | out lep,temp ;LED aus
|
82 |
|
83 | out tap+2,temp ;Pull-Ups für Tasten einschalten (PORTx=PINx+2)
|
84 | ldi temp, 0x00
|
85 | out tap+1,temp ;Ports d = Eingang (DDRx=PINx+1)
|
86 |
|
87 | cbi ship+1,shib ;Shift-Tastenanschluss als Eingang
|
88 | sbi ship+2,shib ;Shift-PullUp einschalten
|
89 |
|
90 | ldi temp, 0x01
|
91 | out tccr0, temp ;Timertakt = 1:1
|
92 | ldi temp, 1<<toie0
|
93 | out timsk, temp ;Timer OVF freigeben
|
94 | ldi temp,timerwert+12 ;Timer-Startwert, korregiert mit Int-Aufruf
|
95 | mov tsw,temp ;definieren
|
96 | out tcnt0,tsw ;und ausgeben
|
97 |
|
98 | ldi temp, 50
|
99 | mov soll0, temp ;Naja, wenn es sein muss...
|
100 | ldi temp,1<<se ;Sleep-Mode (idle)
|
101 | out mcucr,temp ;freischalten
|
102 | ldi max,pwu ;Max-Wert für Begrenzung der Änderung
|
103 | sei
|
104 |
|
105 | Haupt: ;Hauptschleife, Auswertung der Tastenflags,
|
106 | ;die in der ISR gesetzt wurden und verändern
|
107 | ;der PWM-Werte der 8 Kanäle.
|
108 | sleep ;Schlafmodus, Wecken erfolgt durch Timer-Int.
|
109 | tst tfl ;Ein Bit im Tastenflag gesetzt?
|
110 | breq haupt ;nein, keine Taste gedrückt gewesen... (schlafen gehen...)
|
111 | ldi ri,step ;ja, erstmal aufwärts zählen
|
112 | sbis ship,shib ;Shift-Taste gedrückt? (nein...)
|
113 | rjmp minus ;ja, zum Abwärtszählen...
|
114 | taste0:
|
115 | sbrs tfl,0 ;Taste 0?
|
116 | rjmp taste1 ;nein...
|
117 | add soll0,ri ;ja, ändern
|
118 | cp soll0,max ;Maxwert überschritten?
|
119 | brlo taste1 ;nein...
|
120 | mov soll0,max ;ja, auf Maxwert begrenzen
|
121 | taste1:
|
122 | sbrs tfl,1 ;Taste 1?
|
123 | rjmp taste2 ;nein...
|
124 | add soll1,ri ;ja, ändern
|
125 | cp soll1,max ;Maxwert überschritten?
|
126 | brlo taste2 ;nein...
|
127 | mov soll1,max ;ja, auf Maxwert begrenzen
|
128 | taste2:
|
129 | sbrs tfl,2 ;Taste 2?
|
130 | rjmp taste3 ;nein...
|
131 | add soll2,ri ;ja, ändern
|
132 | cp soll2,max ;Maxwert überschritten?
|
133 | brlo taste3 ;nein...
|
134 | mov soll2,max ;ja, auf Maxwert begrenzen
|
135 | taste3:
|
136 | sbrs tfl,3 ;Taste 3?
|
137 | rjmp taste4 ;nein...
|
138 | add soll3,ri ;ja, ändern
|
139 | cp soll3,max ;Maxwert überschritten?
|
140 | brlo taste4 ;nein...
|
141 | mov soll3,max ;ja, auf Maxwert begrenzen
|
142 | taste4:
|
143 | sbrs tfl,4 ;Taste 4?
|
144 | rjmp taste5 ;nein...
|
145 | add soll4,ri ;ja, ändern
|
146 | cp soll4,max ;Maxwert überschritten?
|
147 | brlo taste5 ;nein...
|
148 | mov soll4,max ;ja, auf Maxwert begrenzen
|
149 | taste5:
|
150 | sbrs tfl,5 ;Taste 5?
|
151 | rjmp taste6 ;nein...
|
152 | add soll5,ri ;ja, ändern
|
153 | cp soll5,max ;Maxwert überschritten?
|
154 | brlo taste6 ;nein...
|
155 | mov soll5,max ;ja, auf Maxwert begrenzen
|
156 | taste6:
|
157 | sbrs tfl,6 ;Taste 6?
|
158 | rjmp taste7 ;nein...
|
159 | add soll6,ri ;ja, ändern
|
160 | cp soll6,max ;Maxwert überschritten?
|
161 | brlo taste7 ;nein...
|
162 | mov soll6,max ;ja, auf Maxwert begrenzen
|
163 | taste7:
|
164 | sbrs tfl,7 ;Taste 7?
|
165 | rjmp taste8 ;nein...
|
166 | add soll7,ri ;ja, ändern
|
167 | cp soll7,max ;Maxwert überschritten?
|
168 | brlo taste8 ;nein...
|
169 | mov soll7,max ;ja, auf Maxwert begrenzen
|
170 | taste8:
|
171 | clr tfl ;alle Tastenflags löschen
|
172 | rjmp haupt ;fertig, schlafen gehen...
|
173 | minus:
|
174 | sbrs tfl,0 ;Taste 0?
|
175 | rjmp minus1 ;nein...
|
176 | sub soll0,ri ;ja, ändern
|
177 | brcc minus1 ;Unterlauf ? (nein...)
|
178 | clr soll0 ;ja, auf 0 setzen
|
179 | minus1:
|
180 | sbrs tfl,1 ;Taste 1?
|
181 | rjmp minus2 ;nein...
|
182 | sub soll1,ri ;ja, ändern
|
183 | brcc minus2 ;Unterlauf ? (nein...)
|
184 | clr soll1 ;ja, auf 0 setzen
|
185 | minus2:
|
186 | sbrs tfl,2 ;Taste 2?
|
187 | rjmp minus3 ;nein...
|
188 | sub soll2,ri ;ja, ändern
|
189 | brcc minus3 ;Unterlauf ? (nein...)
|
190 | clr soll2 ;ja, auf 0 setzen
|
191 | minus3:
|
192 | sbrs tfl,3 ;Taste 3?
|
193 | rjmp minus4 ;nein...
|
194 | sub soll3,ri ;ja, ändern
|
195 | brcc minus4 ;Unterlauf ? (nein...)
|
196 | clr soll3 ;ja, auf 0 setzen
|
197 | minus4:
|
198 | sbrs tfl,4 ;Taste 4?
|
199 | rjmp minus5 ;nein...
|
200 | sub soll4,ri ;ja, ändern
|
201 | brcc minus5 ;Unterlauf ? (nein...)
|
202 | clr soll4 ;ja, auf 0 setzen
|
203 | minus5:
|
204 | sbrs tfl,5 ;Taste 5?
|
205 | rjmp minus6 ;nein...
|
206 | sub soll5,ri ;ja, ändern
|
207 | brcc minus6 ;Unterlauf ? (nein...)
|
208 | clr soll5 ;ja, auf 0 setzen
|
209 | minus6:
|
210 | sbrs tfl,6 ;Taste 6?
|
211 | rjmp minus7 ;nein...
|
212 | sub soll6,ri ;ja, ändern
|
213 | brcc minus7 ;Unterlauf ? (nein...)
|
214 | clr soll6 ;ja, auf 0 setzen
|
215 | minus7:
|
216 | sbrs tfl,7 ;Taste 7?
|
217 | rjmp minus8 ;nein...
|
218 | sub soll7,ri ;ja, ändern
|
219 | brcc minus8 ;Unterlauf ? (nein...)
|
220 | clr soll7 ;ja, auf 0 setzen
|
221 | minus8:
|
222 | clr tfl ;alle Tastenflags löschen
|
223 | rjmp haupt ;Hauptprogramm Endlosschleife
|
224 |
|
225 |
|
226 | Tim0_OVF: ;ISR Timer0-Überlauf
|
227 | in sregtemp, sreg ;Sreg sichern
|
228 | out tcnt0,tsw ;Timer auf Startwert setzen
|
229 | inc pwz ;PWM-Treppenzähler erhöhen
|
230 | cpi pwz, pwu ;PWM-Zählumfang erreicht?
|
231 | brne Time0_a ;nein... (die 3 Punkte bedeuten bei mir Sprung)
|
232 | clr pwz ;von vorn beginnen mit zählen
|
233 | Time0_a: ;Vergleich der einzelnen PWM-Werte mit dem PWM-Treppenzähler
|
234 | ;(Idee geklaut bei Peter Dannegger)
|
235 | cp pwz, soll7 ;Sollwert erreicht? (Ergebnis im Carry)
|
236 | rol temp ;Carry-Bits "einsammeln", dieses wird bis Bit7 durchgeschoben
|
237 | cp pwz, soll6
|
238 | rol temp ;Bit 6
|
239 | cp pwz, soll5
|
240 | rol temp ;Bit 5
|
241 | cp pwz, soll4
|
242 | rol temp ;Bit 4
|
243 | cp pwz, soll3
|
244 | rol temp ;Bit 3
|
245 | cp pwz, soll2
|
246 | rol temp ;Bit 2
|
247 | cp pwz, soll1
|
248 | rol temp ;Bit 1
|
249 | cp pwz, soll0
|
250 | rol temp ;Bit 0
|
251 | com temp ;invertieren da low-aktive LED im STK500
|
252 | out portB, temp ;Ausgabe
|
253 | inc task ;Taskscheibe erhöhen (Tastenabfrage erfolgt nur bei Task Nr. 0)
|
254 | ;andere Aufgaben können bei anderen Zählerständen aufgerufen werden
|
255 | ;dabei ist darauf zu achten, dass kein Durchlauf der ISR mehr als
|
256 | ;70 Takte dauert, da die ISR alle 100 Takte aufgerufen wird und
|
257 | ;der Aufruf (mit Reti) schon 10 Takte braucht.
|
258 | brne timertasks ;nur bei 0 Tasten abfragen...
|
259 | Tastenabfrage: ;Entprellroutine (geklaut bei Peter Dannegger...)
|
260 | in scan,tap ;Tastenport einlesen (gedrückt=L)
|
261 | com scan ;invertieren (gedrückt=H)
|
262 | eor scan,tas ;nur Änderungen werden H
|
263 | and tz0,scan ;Prellzähler unveränderter Tasten löschen (Bit0)
|
264 | and tz1,scan ;Prellzähler unveränderter Tasten löschen (Bit1)
|
265 | com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0
|
266 | eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln
|
267 | and scan,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler
|
268 | and scan,tz1 ;beide Bits gesetzt sind (Zählerstand 3)
|
269 | eor tas,scan ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
|
270 | and scan,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten
|
271 | or tfl,scan ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
|
272 | ;in "tas" steht jetzt der gültige Tastenzustand,
|
273 | ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten...
|
274 | timertasks:
|
275 | cpi task,2 ;Beispiel für Verzweigung nach Taskscheibe
|
276 | brne timerfertig ;bei falscher Tasknummer Überspringen...
|
277 | ;Task 2, hier können weitere Aufgaben erledigt werden
|
278 |
|
279 | timerfertig:
|
280 | out sreg, sregtemp ;Sreg wiederherstellen
|
281 | reti ;ISR fertig
|