fptest10.asm


1
;****************************************************************************************
2
;*                                                                                      *
3
;*                          Testprogramm variable PWM                                   *
4
;*                                                                                      *
5
;*                        Controller: 8515   Clock  = 4 MHz                             *
6
;*                                                                                      *
7
;*                                                                                      *
8
;*    Stand: 25.5.03                                                                    *
9
;*                                                                                      *
10
;*    PWM Variabel,Frequenz variabel                                                    *
11
;*                                                                                      *
12
;*    Rechenroutine zur Bestimmumg des Puls / Pausenverhältnisses aus                   *
13
;*    gewählter Frequenz und Ansteuerung Port B über Drehimpulsgeber.                   *
14
;*                                                                                      *
15
;*    do: Grenzwertberchnung                                                            *
16
;*                                                                                      *
17
;*                                                                                      *
18
;*                                                                                      *
19
;****************************************************************************************
20
21
22
.include "C:\vmlab\include\4414def.inc"
23
.list
24
25
26
.def  stat     =  r13      ;Statusregister Hauptprogramm
27
.def  addlo    =  r16      ;Hilfsregister addition Timersektion
28
.def  fahrt    =  r17      ;Register fuer Fahrtstufe
29
30
.def  workh    =  r20      ;Speicherregister Hauptprogramm
31
.def  workl    =  r21      ;Speicherregister Timersektion
32
33
.def  temp1    =  r18      ;mehrzweck
34
.def  temp2    =  r19      ;mehrzweck
35
.def  temp3    =  r24      ;mehrzweck
36
.def  temp4    =  r25      ;mehrzweck
37
.def  lpause   =  r26      ;lowbyte pause
38
.def  hpause   =  r27      ;highbyte pause
39
.def  lpuls    =  r28      ;lowbyte impuls
40
.def  hpuls    =  r29      ;highbyte impuls
41
42
.def  drem16ul =  r14      ;remainder lowbyte
43
.def  drem16uh =  r15      ;remainder highbyte
44
.def  dres16ul =  r16      ;Ergebniss division lowbyte
45
.def  dres16uh =  r17      ;Ergebniss division highbyte
46
.def  dd16ul   =  r16      ;divident lowbyte
47
.def  dd16uh   =  r17      ;divident highbyte
48
.def  dv16ul   =  r18      ;divisor lowbyte
49
.def  dv16uh   =  r19      ;divisor highbyte
50
51
52
.def  mc16ul   =  r16      ;multiplicand lowbyte
53
.def  mc16uh   =  r17      ;multiplicand highbyte
54
.def  mp16ul   =  r18      ;multiplier lowbyte
55
.def  mp16uh   =  r19      ;multiplier highbyte
56
.def  m16u0    =  r18      ;Ergebniss byte 0 (LSB)
57
.def  m16u1    =  r19      ;Ergebniss byte 1
58
.def  m16u2    =  r20      ;Ergebniss byte 2
59
.def  m16u3    =  r21      ;Ergebniss byte 3 (MSB)
60
61
.def  cnt      =  r22      ;Counter für Rechenroutinen
62
63
.equ  startwert=  23       ;PWM auf 95% Pausenzeit festlegen
64
.equ  frequenz =  6240     ;Dezimalwert für Frequenz
65
.equ  step    =  1
66
67
68
rjmp           initial     ;Controler initialisieren
69
reti                       ;externer Interrupt0, noch frei
70
reti
71
reti                       ;capture Interrupt, noch frei
72
rjmp           timer1compa ;Timer1 Compare A  Interrupt
73
reti
74
reti
75
rjmp        t1_ovfl    ;Counter 0 Überlauf, Erkennung Drehimpulsgeber
76
reti
77
reti
78
reti
79
reti
80
reti
81
82
83
initial:
84
85
ldi   workh,high(ramend)
86
out   sph,workh
87
ldi   workh,low(ramend)
88
out   spl,workh
89
ldi   workh,$20            ;PD5 ist Ausgang PWM Signal, Rest ist Eingang
90
out   ddrd,workh
91
ldi   workh,$df
92
out   portd,workh          ;Eingänge Port D Pullups aktiviert
93
clr   workh
94
out   ddrb,workh           ;port b ist eingang
95
ser   workh
96
out   portb,workh          ;Pullups Port b aktiviert
97
out  ddrc,workh        ;Port C ist Ausgang
98
99
ldi  workh,$42
100
out  timsk,workh        ;Timer / Counter 0 Interruptfreigabe
101
ldi  workh,$fe
102
out  tcnt0,workh        ;Timerzählregister auf 255 setzen
103
ldi  workh,$07
104
out  tccr0,workh        ;Timer 0 = Countermode, steigende Flanke an PB 0
105
106
sei
107
;---------------------------------------------------------------------------------
108
;I                               Hauptprogramm                                   I
109
;---------------------------------------------------------------------------------
110
111
112
main:
113
114
;----------- 1.Berechnung prozentualer Anteil P/P - Grundwert
115
116
117
118
;1.division, Faktor errechnen und Ergebniss in r16 und r17
119
120
ldi   dd16ul,low(frequenz)
121
ldi   dd16uh,high(frequenz)
122
ldi   dv16ul,low(24)
123
ldi   dv16uh,high(24)
124
rcall calc1
125
sts   $0065,dres16ul
126
sts   $0064,dres16uh
127
128
129
;2. Multiplikation, Ergebniss Pausenzeit in m16u0 - m16u3
130
131
ldi   mp16ul,low(startwert)     ;Multiplikator lowbyte
132
ldi   mp16uh,high(startwert)    ;Multiplikator highbyte
133
rcall calc2
134
135
;3. Pulszeit errechnen, PWM starten
136
137
mov   lpause,m16u0         ;lowbyte Pause nach lpause schieben
138
mov   hpause,m16u1         ;highbyte Pause nach hpause schieben
139
rcall calc3
140
141
;4. unteren Grenzwert berechnen
142
143
ldi  mp16ul,low(1)
144
ldi  mp16uh,high(1)
145
rcall  calc2
146
sts  $0066,m16u1
147
sts  $0067,m16u0
148
rcall  calc3
149
sts  $0068,hpuls
150
sts  $0069,lpuls
151
152
;5. oberen Grenzwert berechnen
153
154
ldi  mp16ul,low(23)
155
ldi  mp16uh,high(23)
156
rcall  calc2
157
sts  $006a,m16u1
158
sts  $006b,m16u0
159
rcall  calc3
160
sts  $006c,hpuls
161
sts  $006d,lpuls
162
163
164
ldi   workh,$01
165
sts   $0070,workh        ;speicherstelle Fahrtstufe
166
167
rcall startpwm             ;Grundwerte Pause setzen
168
169
loop:
170
lds   hpause,$60           ;aktueller wert Pause (highbyte)
171
lds   lpause,$61           ;aktueller wert Pause (lowbyte)
172
lds   hpuls,$62            ;aktueller wert Impuls (highbyte)
173
lds   lpuls,$63            ;aktueller wert Impuls (lowbyte)
174
lds  temp1,$0070
175
out  portc,temp1
176
rjmp  loop
177
178
179
180
181
182
183
;---------------------------------------------------------------------------------
184
;I                           PWM Interrupt Routine                               I
185
;---------------------------------------------------------------------------------
186
187
startpwm:
188
189
sts   $0060,hpause
190
sts   $0061,lpause
191
sts   $0062,hpuls
192
sts   $0063,lpuls
193
194
out   ocr1ah,hpause        ;speichern high byte PAUSE (toff) ocr1a
195
out   ocr1al,lpause        ;speichern low byte PAUSE (toff) ocr1a
196
ldi   workh,$c0
197
out   tccr1a,workh         ;nach 1. Comp.A Interrupt ->1
198
ldi   workh,$02            ;T/C1 clock = Systemclock/8
199
out   tccr1b,workh         ;Start T/C1
200
201
202
ldi   workh,$42
203
out   timsk,workh          ;set Comp. A Interrupt (+ Timer 0 Interrupt)
204
205
sei
206
207
ret
208
209
;------------------------------ Interruptroutine PWM ----------------------------
210
211
212
timer1compa:
213
214
in    stat,sreg            ;retten sreg
215
;clr   workh
216
;out   gimsk,workh          ;int1 sperren
217
com   lpuls
218
com   hpuls                ;1er Komplement bilden hpuls
219
com   lpause               ;lpause invertieren
220
com   hpause               ;hpause negieren
221
222
in    workl,tccr1a         ;T/C1 control register A
223
sbrs  workl,com1a0         ;Befehl überspringen wenn  com1a0 =1
224
225
rjmp  tc1                  ;springen wenn com1a0 = 0
226
227
cbr   workl,1<<com1a0      ;next interrupt oc1a -> 0
228
out   tccr1a,workl         ;speichern  tccr1a
229
in    addlo,ocr1al         ;holen low byte ocr1a
230
sub   addlo,lpuls          ;und addieren low byte ton
231
in    workl,ocr1ah         ;high byte ocr1a
232
sbc   workl,hpuls          ;addieren high byte ton
233
234
rjmp  intende
235
236
237
tc1:
238
239
sbr   workl,1<<com1a0      ;next interrupt oc1a -> 1
240
out   tccr1a,workl         ;neuen Wert zurückspeichern
241
in    addlo,ocr1al         ;hole low byte ocr1a
242
sub   addlo,lpause         ;addiere low byte toff
243
in    workl,ocr1ah         ;nächstes byte ocr1
244
sbc   workl,hpause         ;und addieren high byte toff
245
246
247
248
intende:
249
250
out   ocr1ah,workl         ;speichern neues high byte ocr1a
251
out   ocr1al,addlo         ;speichern neues low byte ocr1a
252
out   sreg,stat            ;SREG wiederherstellen
253
reti
254
255
; Ende PWM Routine
256
257
;---------------------------------------------------------------------------------
258
;I                        Drehgeber-Interruptroutine                             I
259
;---------------------------------------------------------------------------------
260
261
262
t1_ovfl:
263
264
in    temp3,sreg        ;SREG sichern
265
push  workh
266
lds  fahrt,$0070          ;aktuellen Wert Fahrtsufe holen
267
in    workh,pinb        ;Bitmuster Eingang Port B holen
268
sbrs  workh,1          ;Bit an PB1 = H ?
269
rjmp  down            ;wenn ja, dann nach "down"
270
ldi  workh,low(step)    ;Wert für Schrittweite holen
271
add  fahrt,workh        ;Schrittweite addieren und in "Fahrt" speichern
272
rcall  ogrenzwert        ;Zur Routine "oberer Grenzwert erreicht?"
273
rjmp  end_t0int
274
275
down:
276
subi  fahrt,step        ;Wert für Fahrtstufe verringern
277
rcall  ugrenzwert           ;Zur Routine "unterer Grenzwert erreicht?"
278
sts  $0070,fahrt        ;Wert für Fahrtstufe in SRAM sichern
279
rjmp  end_t0int
280
281
282
ogrenzwert:
283
ldi  workh,$17        ;maxwert 24 für oberen Grenzwert
284
cp    fahrt,workh        ;Fahrtstufe mit Grenzwert vergleichen
285
brsh  setmax          ;wenn gleich oder größer, maxwert festlegen
286
ret                ;sonst zurück
287
288
setmax:
289
ldi  fahrt,$17        ;maxwert ist 230
290
ret
291
292
293
ugrenzwert:
294
ldi  workh,$00        ;unterer Grenzwert = 0
295
cp    fahrt,workh        ;Fahrtstufe mit Grenzwert vergleichen
296
breq  setmin          ;wenn = erreicht, Wert festlegen
297
ret
298
299
setmin:
300
ldi  fahrt,$01        ;minwert Fahrtstufe ist 1
301
ret
302
303
end_t0int:
304
sts  $0070,fahrt        ;neuen Wert für Fahrtstufe in SRAM sichern
305
rcall  fahrtstufe
306
ldi  workh,$ff        
307
out  tcnt0,workh        ;Counter-Register auf 255 setzen
308
pop  workh
309
out  sreg,temp3
310
reti
311
312
fahrtstufe:
313
ldi  temp1,$02
314
out  timsk,temp1
315
lds  mc16ul,$65        ;Konstante aus "calc1" lowbyte aus SRAM holen
316
lds  mc16uh,$64        ;Konstante aus "calc1" highbyte aus SRAM holen
317
lds  mp16ul,$70        ;Wert für Fahrtstufe lowbyteaus SRAM holen
318
ldi  mp16uh,$00        ;highbyte Fahrtstufe auf 0 setzen
319
rcall  calc2            ;Multiplikation aufrufen
320
sts  $0063,m16u0        ;Ergebniss lowbyte Pulsdauer in SRAM sichern
321
sts  $0062,m16u1        ;Ergebniss highbyte Pulsdauer in SRAM sichern
322
mov  lpuls,m16u0        ;lowbyte Pulsdauer nach lpuls schieben
323
mov  hpuls,m16u1        ;highbyte Pulsdauer nach hpuls schieben
324
rcall  calc4            ;Subtraktion Frequenz-Pulsdauer aufrufen
325
sts  $0060,hpause      ;Ergebniss highbyte Pausendauer in SRAM sichern
326
sts  $0061,lpause      ;Ergebniss lowbyte Pausendauer in SRAM sichern
327
ldi  temp1,$42
328
out  timsk,temp1
329
ret    
330
331
;---------------------------------------------------------------------------------
332
;I                              Rechenroutinen                                   I
333
;---------------------------------------------------------------------------------
334
335
336
;--------------- 16 / 16bit Division
337
338
calc1:
339
div16u:
340
clr   drem16ul             ;Hilfsregister lowbyte lschen
341
sub   drem16uh,drem16uh    ;Hilfsregister highbyte und carry lschen
342
ldi   cnt,17               ;Schleifenzhler initialisieren
343
344
345
d16u_1:
346
rol   dd16ul               ;lowbyte dividend links schieben
347
rol   dd16uh               ;highbyte dividend links schieben
348
dec   cnt                  ;Schleifenzhler um 1 runterzhlen
349
brne  d16u_2
350
ret
351
352
d16u_2:
353
rol   drem16ul             ;lowbyte dividend im Hilfsregister schieben
354
rol   drem16uh             ;highbyte dividend im Hilfsregister schieben
355
sub   drem16ul,dv16ul      ;lowbyte divisor von temp1 abziehen
356
sbc   drem16uh,dv16uh      ;highbyte divisor von temp2 abziehen
357
brcc  d16u_3               ;wenn Ergebniss negativ, springen nach "bertrag"
358
add   drem16ul,dv16ul
359
adc   drem16uh,dv16uh
360
clc
361
rjmp  d16u_1
362
363
d16u_3:
364
sec
365
rjmp  d16u_1
366
367
368
;--------------- 16 * 16bit Multiplikation
369
370
calc2:
371
372
clr   m16u3
373
clr   m16u2
374
ldi   cnt,16
375
lsr   mp16uh
376
ror   mp16ul
377
m16u_1:
378
brcc  noadd8
379
add   m16u2,mc16ul
380
adc   m16u3,mc16uh
381
382
noadd8:
383
ror   m16u3
384
ror   m16u2
385
ror   m16u1
386
ror   m16u0
387
dec   cnt
388
brne  m16u_1
389
390
ret
391
392
;--------------- 16 - 16bit Subtraktion
393
394
calc3:
395
ldi   workh,low(frequenz)  ;lowbyte von Sollfrequenz holen
396
sub   workh,lpause         ;lowbyte von Pausenzeit abziehen
397
mov   lpuls,workh          ;Wert nach lowbyte Impuls schieben
398
ldi   workh,high(frequenz) ;highbyte von Sollfrequenz holen
399
sbc   workh,hpause         ;Pausenzeit mit Uebertrag subtrahieren
400
mov   hpuls,workh          ;Wert nach highbyte Impuls schieben
401
402
ret
403
404
405
calc4:
406
ldi   workh,high(frequenz)  ;lowbyte von Sollfrequenz holen
407
sub   workh,hpuls         ;lowbyte von Pausenzeit abziehen
408
mov   hpause,workh          ;Wert nach lowbyte Impuls schieben
409
ldi   workh,low(frequenz) ;highbyte von Sollfrequenz holen
410
sbc   workh,lpuls         ;Pausenzeit mit Uebertrag subtrahieren
411
mov   lpause,workh          ;Wert nach highbyte Impuls schieben
412
413
ret