test2.5.asm


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
.nolist                     ;List der Include-Datei unterdrücken
11
.include "m8515def.inc"
12
.list                       ;Programm listen
13
.listmac                    ;Makros listen
14
.equ clock = 8000000        ;Taktfrequenz 8Mhz
15
;.equ clock = 16000000        ;Taktfrequenz 8Mhz
16
17
18
19
.equ pwu = 50               ;PWM-Zählumfang
20
.equ timerwert = -100       ;Timer-Startwert (Reload)-100
21
.equ step=5 ; 6                 ;Schrittweite für Änderung pro Tastendruck
22
.equ lep=portb              ;Port für LEDs
23
.equ tap=pinc               ;Tastenport
24
.equ ruck      = 4          ;Taste zurück
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 alltast=(1<<ruck)|(1<<dimplus)|(1<<dimminus)|(1<<chanplus)|(1<<chanminus)  ;Maske aller Tasten
30
31
.equ avt0=20                ;Startwert Anzeige-Vorteiler
32
33
34
.def soll0 = r0             ;Sollwert Kanal 1
35
.def soll1 = r1             ;Sollwert Kanal 2
36
.def soll2 = r2             ;Sollwert Kanal 3
37
.def soll3 = r3             ;Sollwert Kanal 4
38
.def soll4 = r4             ;Sollwert Kanal 5
39
.def soll5 = r5             ;Sollwert Kanal 6
40
.def soll6 = r6             ;Sollwert Kanal 7
41
.def soll7 = r7             ;Sollwert Kanal 8
42
.def tsw = r8               ;Timer-Startwert
43
.def sregtemp = r9          ;Sicherheitskopie SREG
44
.def scan=r10               ;Scannwert Tastenport
45
.def tz0=r11                ;Tasten-Prellzähler Bit0
46
.def tz1=r12                ;Tasten-Prellzähler Bit1
47
.def tas=r13                ;Tastenstatus (gültig)
48
.def null=r14               ;immer 0
49
50
;********************************************  
51
52
;********************************************
53
.def temp = r16
54
.def tfl=r17                ;Flags für Tasten, die gedrückt wurden
55
.def pwz = r18              ;PWM-Zähler
56
57
.def task=r19               ;Taskscheibe für diverse Aufgaben
58
.def ri=r20                 ;Richtung der Änderung
59
.def max=r21                ;Maximum
60
61
62
 
63
64
65
.def avt=r22                ;Anzeige-Vorteiler
66
.def flags=r23              ;Steuerflags
67
    .equ aktuLCD=7 ;7              ;LCD aktualisieren
68
69
.def wl=r24                 ;Working L
70
.def wh=r25                 ;Working H
71
72
73
74
 .equ lcdcontroller1=4       ;Flag für Controller 1
75
 .equ lcdcontroller2=6       ;Flag für Controller 2
76
77
78
79
80
81
.cseg
82
;.org 0                      ;Reset- und Interrupt-Vektoren Mega 8535
83
.org 0              ;Reset- und Interrupt-Vektoren AT-Mega 8515
84
 rjmp RESET         ;Reset Handler
85
 rjmp nix;EXT_INT0      ;IRQ0 Handler
86
 rjmp nix;EXT_INT1      ;IRQ1 Handler
87
 rjmp nix;TIM1_CAPT     ;Timer1 Capture Handler
88
 rjmp nix;TIM1_COMPA    ;Timer1 Compare A Handler
89
 rjmp nix;TIM1_COMPB    ;Timer1 Compare B Handler
90
 rjmp nix;TIM1_OVF      ;Timer1 Overflow Handler
91
 rjmp TIM0_OVF      ;Timer0 Overflow Handler
92
 rjmp nix;SPI_STC       ;SPI Transfer Complete Handler
93
 rjmp nix;USART_RXC     ;USART RX Complete Handler
94
 rjmp nix;USART_UDRE    ;UDR0 Empty Handler
95
 rjmp nix;USART_TXC     ;USART TX Complete Handler
96
 rjmp nix;ANA_COMP      ;Analog Comparator Handler
97
 rjmp nix;EXT_INT2      ;IRQ2 Handler
98
 rjmp nix;TIM0_COMP     ;Timer0 Compare Handler
99
 rjmp nix;EE_RDY        ;EEPROM Ready Handler
100
 rjmp nix;SPM_RDY       ;Store Program memory Ready Handler
101
nix:                    ;unbenutzte Interrupts
102
 reti                   ;zurück...
103
104
105
106
107
108
109
.include"LCDprint.inc"      ;LCD-Ausgabefunktionen
110
.include"LCD_4x27.inc"      ;LCD-Routinen für 4-Zeilen-LCDs mit HD44780
111
112
113
114
115
116
117
Reset:
118
119
 ldi wl,low(ramend)         ;Stackpointer initialisieren
120
 out SPL,wl
121
 ldi wl,high(ramend)
122
 out SPH,wl
123
 
124
 clr null                   ;immer 0
125
126
 ldi wl, 0xFF    ;Port A = Ausgang
127
 out DDRA, wl    ;Display
128
129
 ldi temp, 0xFF    ;Port E = Ausgang
130
 out DDRE, temp
131
132
133
 ldi temp, 0xff
134
 out lep-1,temp             ;Ports B = Ausgang (DDRx=PORTx-1)
135
136
137
 ;out lep,temp               ;LED aus
138
 
139
 ldi wl, alltast              ;pull-ups 
140
 out tap+2,wl                 ;für tasten einschalten
141
  
142
143
  ldi R16, 0x00                       ; PORTD Eingang
144
  out DDRD, R16
145
        
146
     sbi portd,0                          ; pullupwid.
147
     sbi portd,1                          ; pullupwid. 
148
        
149
150
;***********************************************
151
 
152
;************************************************
153
154
 clr soll0
155
 clr soll1
156
 clr soll2
157
 clr soll3
158
 clr soll4
159
 clr soll5
160
 clr soll6
161
 clr soll7
162
 clr tz0                    ;Definierte Startbedingung 
163
 clr tz1                    ;für Tastenentprellung
164
 clr tas
165
 clr tfl
166
167
 
168
169
;TIMER0
170
  ldi temp, 0x01
171
 out tccr0, temp            ;Timertakt = 1:1
172
 ldi temp, 1<<toie0
173
 out timsk, temp            ;Timer OVF freigeben
174
 ldi temp,timerwert+12      ;Timer-Startwert, korregiert mit Int-Aufruf12
175
 mov tsw,temp               ;definieren
176
  out tcnt0,tsw              ;und ausgeben
177
 
178
 
179
180
 ldi temp,  0 ;50
181
 mov soll0, temp            ;Naja, wenn es sein muss...
182
 ldi temp,1<<se             ;Sleep-Mode (idle)
183
 out mcucr,temp             ;freischalten
184
 ldi max,pwu                ;Max-Wert für Begrenzung der Änderung
185
186
 
187
188
189
190
rcall lcd_init             ;LCD initialisieren      
191
192
193
194
 
195
  sei  ;INTERRUPST FREIGEBEN
196
197
198
 tastaus:                ;Tasten puffer leeren und mainloop
199
 clr tfl                    ;Tastenflags löschen
200
 rjmp mainloop1              
201
202
                  ;Hauptschleife, Auswertung der Tastenflags
203
204
 
205
 sbrc flags,aktuLCD         ;muss LCD aktualisiert werden? - nein...
206
               
207
208
mainloop1:
209
210
 andi tfl,alltast           ;nur benutzte Tasten prüfen
211
  rjmp menu                  ;Tastendruck auswerten...
212
213
  
214
215
menu:
216
217
M0:
218
 sbrC tfl,chanplus               ;kanal hoch Taste? nein...
219
 RJMP channel1                  ;ja...
220
221
M1:
222
 sbrC tfl,chanplus               ;kanal hoch Taste? nein...
223
 RJMP channel2                  ;ja...
224
 
225
M2:
226
 sbrc tfl,chanplus               ;kanal hoch Taste? nein...
227
 RJMP channel3                  ;ja...
228
 
229
M3:
230
 sbrc tfl,chanplus               ;kanal hoch Taste? nein...
231
 RJMP channel4                  ;ja...
232
 ;cbr tfl,(1<<chanplus)
233
 cbr tfl,alltast            ;alle Tasten sind erledigt
234
 rjmp tastaus
235
;***********************************************************************
236
237
238
channel1:
239
 locate 0,0
240
 printf CHAN1
241
CC1:
242
 ldi ri,step                ;ja, erstmal aufwärts zählen
243
 sbrs tfl,dimplus                 ;Taste ?
244
 rjmp m0                 ;nein...
245
 add soll0,ri         ;ja, ändern
246
 cp soll0,max               ;Maxwert überschritten?
247
 brlo FF3                ;nein...
248
 mov soll0,max              ;ja, auf Maxwert begrenzen  
249
 FF3:
250
;cbr tfl,(1<<dimplus)
251
  rjmp tastaus
252
253
channel2:
254
 locate 0,0
255
 printf CHAN2
256
CC2:
257
 ldi ri,step                ;ja, erstmal aufwärts zählen
258
 sbrs tfl,dimplus                 ;Taste ?
259
 rjmp m1                 ;nein...
260
 add soll1,ri         ;ja, ändern
261
 cp soll1,max               ;Maxwert überschritten?
262
 brlo FF4                ;nein...
263
 mov soll1,max              ;ja, auf Maxwert begrenzen  
264
 FF4:
265
;cbr tfl,(1<<dimplus)
266
 rjmp tastaus
267
268
269
channel3:
270
 locate 0,0
271
 printf CHAN3
272
CC3:
273
 ldi ri,step                ;ja, erstmal aufwärts zählen
274
 sbrs tfl,dimplus                 ;Taste ?
275
 rjmp m2                 ;nein...
276
 add soll2,ri         ;ja, ändern
277
 cp soll2,max               ;Maxwert überschritten?
278
 brlo FF5                ;nein...
279
 mov soll2,max              ;ja, auf Maxwert begrenzen  
280
 FF5:
281
;cbr tfl,(1<<dimplus)
282
 rjmp tastaus
283
284
channel4:
285
 locate 0,0
286
 printf CHAN4
287
CC4:
288
 ldi ri,step                ;ja, erstmal aufwärts zählen
289
 sbrs tfl,dimplus                 ;Taste ?
290
 rjmp m3                 ;nein...
291
 add soll3,ri         ;ja, ändern
292
 cp soll3,max               ;Maxwert überschritten?
293
 brlo FF6                ;nein...
294
 mov soll3,max              ;ja, auf Maxwert begrenzen  
295
 FF6:
296
cbr tfl,(1<<dimplus)
297
 rjmp tastaus
298
299
300
301
302
303
304
305
306
Tim0_OVF:                   ;ISR Timer0-Überlauf
307
 in sregtemp, sreg          ;Sreg sichern
308
 out tcnt0,tsw              ;Timer auf Startwert setzen
309
 inc pwz                    ;PWM-Treppenzähler erhöhen
310
 cpi pwz, pwu               ;PWM-Zählumfang erreicht?
311
 brne Time0_a               ;nein... (die 3 Punkte bedeuten bei mir Sprung)
312
 clr pwz                    ;von vorn beginnen mit zählen
313
Time0_a:                    ;Vergleich der einzelnen PWM-Werte mit dem PWM-Treppenzähler
314
                            ;(Idee geklaut bei Peter Dannegger)
315
 cp pwz, soll7              ;Sollwert erreicht? (Ergebnis im Carry)
316
 rol temp                   ;Carry-Bits "einsammeln", dieses wird bis Bit7 durchgeschoben
317
 cp pwz, soll6
318
 rol temp                   ;Bit 6
319
 cp pwz, soll5
320
 rol temp                   ;Bit 5
321
 cp pwz, soll4
322
 rol temp                   ;Bit 4
323
 cp pwz, soll3
324
 rol temp                   ;Bit 3
325
 cp pwz, soll2
326
 rol temp                   ;Bit 2
327
 cp pwz, soll1
328
 rol temp                   ;Bit 1
329
 cp pwz, soll0
330
 rol temp                   ;Bit 0
331
  ;com temp                   ;invertieren da low-aktive LED im STK500
332
 out portB, temp            ;Ausgabe
333
   inc task                   ;Taskscheibe erhöhen (Tastenabfrage erfolgt nur bei Task Nr. 0)
334
                            ;andere Aufgaben können bei anderen Zählerständen aufgerufen werden
335
                            ;dabei ist darauf zu achten, dass kein Durchlauf der ISR mehr als
336
                            ;70 Takte dauert, da die ISR alle 100 Takte aufgerufen wird und
337
                            ;der Aufruf (mit Reti) schon 10 Takte braucht.
338
 brne timertasks            ;nur bei 0 Tasten abfragen...
339
Tastenabfrage:              ;Entprellroutine (geklaut bei Peter Dannegger...)
340
341
sbis PIND, 0        ;überspringe nächsten Befehl, falls Taster1 nicht
342
rcall LEDon        ;springe Unterprogramm an;
343
sbis PIND, 1 ;1        ;überspringe nächsten Befehl, falls Taster1 gedrückt
344
rcall LEDoff        ;springe Unterprogramm aus 
345
346
 in xl,tap      ;Tastenport einlesen (gedrückt=L)
347
 com xl         ;invertieren (gedrückt=H)
348
 eor xl,tas     ;nur Änderungen werden H
349
 and tz0,xl     ;Prellzähler unveränderter Tasten löschen (Bit0)
350
 and tz1,xl     ;Prellzähler unveränderter Tasten löschen (Bit1)
351
 com tz0        ;L-Bit zählen 0,2,->1, 1,3,->0
352
 eor tz1,tz0    ;H-Bit zählen 0,2,->tz1 toggeln
353
 and xl,tz0     ;Änderungen nur dann erhalten, wenn im Prellzähler
354
 and xl,tz1     ;beide Bits gesetzt sind (Zählerstand 3)
355
 eor tas,xl     ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
356
 and xl,tas     ;nur (neu) gedrückte Tastenbits bleiben erhalten
357
 or tfl,xl      ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
358
359
360
timertasks:
361
 cpi task,2                ;Beispiel für Verzweigung nach Taskscheibe
362
 brne timerfertig           ;bei falscher Tasknummer Überspringen...
363
 dec avt                    ;Anzeige-Vorteiler runter
364
 brne timerfertig           ;unten? nein, weg hier...
365
 ldi avt,avt0               ;ja, Startwert laden
366
 sbr flags,1<<aktuLCD       ;Flag setzen, um LCD zu aktualisieren
367
 
368
  
369
 
370
 
371
timerfertig:
372
373
374
out sreg, sregtemp         ;Sreg wiederherstellen
375
reti                       ;ISR fertig
376
377
378
379
380
381
chan1:    .db "KANAL 1                ",0
382
chan2:    .db "KANAL 2                ",0
383
chan3:    .db "KANAL 3                ",0
384
chan4:    .db "KANAL 4                ",0