PWM_PA0_Uvergleich_5ms_rs232.asm


1
;ausgangsspannungsregelung nach stepdown
2
;pwm an atmega16 für 2 khz
3
;bei 4mhz taktfrequenz
4
;mit timer0 im fast pwm mode, 8 bit aufloesung
5
;pwm-signal liegt auf pb3 oc0
6
;adc takt mittels rcall
7
;rs232 ausgabe+bcd wandlung mittels rcall
8
;werner/16.2.12
9
.include "m16def.inc"
10
11
.def v_panel = r14    ;Messwert PV-Spannung PA0
12
.def v_akku = r12    ;Messwert Akku-Spannung PA1
13
.def i_panel = r10    ;Messwert PV-Strom PA2 
14
.def temp1 = r16    ;temporäre Variable
15
.def temp2 = r17    ;temporäre Variable
16
;.def wait2 = r18    ;Zähler
17
.def v_akkupwm = r19  ;ermittellter Vorladewert ocr0 
18
.def v_store = r20    ;gespeicherte Wunschspannung am PWM-Ausgang
19
20
21
22
.org  0x000     
23
  rjmp RESET    ;External Pin, Power-on Reset, Brown-out
24
.org  INT0addr    
25
  reti      ;External Interrupt Request 0
26
.org  INT1    
27
  reti        ;External Interrupt Request 1
28
.org  OC2addr  
29
  reti        ;Timer/Counter2 Compare Match
30
.org  OVF2addr  
31
  reti        ;Timer/Counter2 Overflow
32
.org  ICP1addr  
33
  reti         ;Timer/Counter1 Capture Event
34
.org  OC1Aaddr  
35
  reti         ;Timer/Counter1 Compare Match A
36
.org  OC1Baddr  
37
  reti         ;Timer/Counter1 Compare Match B
38
.org  OVF1addr  
39
  reti      ;TIMER1 OVF ;Timer/Counter1 Overflow  
40
.org  OVF0addr     
41
  reti       ;Timer/Counter0 Overflow  
42
.org  SPIaddr    
43
  reti        ;Serial Transfer Complete
44
.org  URXCaddr  
45
  reti         ;USART, Rx Complete
46
.org  UDREaddr  
47
  reti       ;USART Data Register Empty
48
.org  UTXCaddr  
49
  reti         ;USART, Tx Complete
50
.org  ADCCaddr      
51
  reti       ;ADC Conversion Complete  
52
.org  ERDYaddr    
53
  reti        ;EEPROM Ready
54
.org  ACIaddr  
55
  reti        ;Analog Comparator
56
.org  TWIaddr  
57
  reti         ;Two-wire Serial Interface
58
.org  INT2addr    
59
  reti        ;External Interrupt Request 2
60
.org  OC0addr  
61
  reti        ;Timer/Counter0 Compare Match
62
.org  SPMRaddr    
63
  reti         ;Store Program Memory Ready
64
65
.org 0x30             ;programm ab flashadresse 30h speichern
66
67
;=============== stackpointer ini ===========================
68
reset:
69
  
70
      ldi temp1, high (RAMEND)
71
      out SPH, temp1  ;SPH am Ende phys. SRAM
72
      ldi temp1, low (RAMEND)
73
      out SPL, temp1  ;SPL am Ende phys. SRAM  
74
      ldi temp1,0b11111000  
75
      out DDRA, temp1    ;pa0-2 analoge eingaenge
76
      ldi temp1,0b11111111   
77
      out DDRD, temp1    ;pd2-7 ausgabe
78
      ldi temp1, 0b11111111      
79
      out DDRC, temp1    ;pc0-7 ausgabe
80
      ldi temp1, 0b00001111
81
      out DDRb, temp1    ;pb0-3 ausgabe
82
            
83
      
84
      ldi v_store,132  ;max.ladespannung rechner.139
85
      ;rcall timer1ini ;TIMER 1 initialisieren
86
      rcall timer0ini ;Timer 0  initialisieren
87
      rcall adini     ;A-D Wandler AD0 initialisieren
88
      rcall rs232ini  ;RS232 initialisieren
89
90
      sei        ;Interrupts global aktivieren?????????
91
;============== hauptprogramm ====================================
92
main:
93
    rcall adwand
94
    rcall auswahl
95
    rcall bin2bcd
96
    rcall rs232aus
97
    rcall warte
98
99
jmp main
100
;============== auswahl+pwm ausgabe ====================================
101
auswahl:
102
      cp v_store, v_akku  ; vergleiche messwert mit sollwert
103
      breq doReturn       ; gleich? dann gibts nichts zu tun
104
      brsh up             ; zu groß?
105
                          ; -> nicht zu groß, also muss es zu klein sein
106
down:      
107
      dec v_akkupwm       ; pwm bischen verringern
108
      jmp sichern
109
      
110
up:      
111
      inc v_akkupwm       ; pwm bischen vergrößern
112
113
sichern:
114
      out ocr0, v_akkupwm ; und externe PWM setzen
115
doReturn:
116
      ret
117
;======================== timer0ini =====================    
118
timer0ini:
119
  
120
  in temp1, tccr0
121
  ori temp1, 0b01101010    ;tccr0, fast pwm, prescaler 8, lösche oc0 bei gleichstand
122
  out  tccr0, temp1
123
  in temp1, timsk
124
  ori temp1, 0b00000000
125
  out timsk, temp1      ;ohne irq
126
127
  ret
128
;====================== ad-wandler ini =================
129
adini:  
130
    
131
    ldi  temp1,(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)  
132
    out  ADCSRA,temp1         ;adcen,
133
        ldi temp1,(1<<REFS0)|(1<<ADLAR)  ;AVcc,linksbuendig,pa0
134
      out ADMUX,temp1
135
ret
136
;======================== adwandlung pa0 ==================
137
adwand:
138
;pa0     
139
      
140
      
141
      sbi  ADCSRA,ADSC    ;Wandlung pa0 starten    
142
fertig:      
143
      sbic ADCSRA,ADSC      ;warten bis wandlung
144
        rjmp fertig        ;beendet    
145
146
      in v_akku, ADCH    ;highbyte auslesen
147
148
ret
149
;================== warte 5ms ===================
150
warte:
151
152
                                 
153
           ldi  temp1, $21
154
WGLOOP0:   ldi  temp2, $C9
155
WGLOOP1:   dec  temp2        ; 5ms Pause (bei 4 MHz)
156
           brne WGLOOP1
157
           dec  temp1
158
           brne WGLOOP0
159
           ret            
160
161
;====================== timer1ini ======================
162
timer1ini:
163
    
164
    ldi  temp1,(1<<CS11)  ;Betriebsart Mode 0 (PB3 normal) 
165
                ;4Mhz/1 Wave Form Generator Mode 0 (Normal)
166
    out TCCR1B, temp1    ;Prescaler 256 um bei TCNT1H + TCNT1L = 0
167
    in temp1, timsk            ;auf ca. 239msek zu kommen
168
    ori temp1, (1<<TOIE1)    ;Timer1 Overflow Interrupt aktiviert    
169
    out TIMSK, temp1
170
    sei            ;Enble all Interrupt
171
    ldi temp1, 0b00000000    ;Lade High Byte des 16 bit Zählers
172
    out TCNT1H, temp1      ;in TCNT1H
173
    ldi temp1, 0b00000000    ;Lade High Byte des 16 bit Zählers
174
    out TCNT1L, temp1      ;in TCNT1L
175
    
176
    ret
177
178
;======================= rs232ini =========================
179
rs232ini:  
180
      LDI temp1, 0      ;Festlegen der Flanke wann gesendet
181
      OUT UBRRH, temp1    ;und gelesen wird
182
      LDI temp1, 26
183
      OUT UBRRL, temp1    ;sende bei 4 MHz mit 9600 Baud
184
      LDI temp1, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)  ;aktiviere tx+rx irq
185
      OUT UCSRB, temp1
186
      LDI temp1,(1<<URSEL)|(0<<USBS)|(3<<UCSZ0)  ; 1 Stopbits, 8 Datenbits 
187
      OUT UCSRC,temp1                ;(fuer 2 Stoppbits USBS=1)
188
      ret
189
190
191
192
;============== rs232 ausgabe===========================
193
rs232aus:
194
195
rs232a:  SBIS UCSRA, UDRE  ;Ausgabe Messwert an RS 232
196
    RJMP rs232a
197
    OUT UDR, R1  
198
199
rs232b:  SBIS UCSRA, UDRE
200
    RJMP rs232b
201
    OUT UDR, R2  
202
203
rs232c:  SBIS UCSRA, UDRE
204
    RJMP rs232c
205
    LDI R23, ','
206
    OUT UDR, R23    
207
208
rs232d:  SBIS UCSRA, UDRE
209
    RJMP rs232d
210
    OUT UDR, R3  
211
212
rs232e:  SBIS UCSRA, UDRE
213
    RJMP rs232e
214
    LDI R23, ' '
215
    OUT UDR, R23
216
217
rs232f:  SBIS UCSRA, UDRE
218
    RJMP rs232f
219
    LDI R23, 'V'
220
    OUT UDR, R23
221
222
rs232g:  SBIS UCSRA, UDRE
223
    RJMP rs232g
224
    LDI R23, ' '
225
    OUT UDR, R23
226
  
227
rs232h:  SBIS UCSRA, UDRE
228
    RJMP rs232h
229
    LDI R23, 13
230
    OUT UDR, R23
231
ret
232
;===================== binaer2bcd-wandlung ======================
233
bin2bcd:
234
235
  CLI
236
  LDI R21, 0        ;Zähler für Durchläufe auf 0  
237
  MOV R22 , R14    ;Lade 253dez in R22
238
  
239
hundertera:
240
  MOV R0,R22        ;Rette Originalwert in R0
241
  CPI R22, 100      ;Prüfe ob hunderter Stelle = 0
242
  BRSH hunderterb
243
  MOV R1, R21        ;schreibe erste Stelle 0
244
  jmp zehnera
245
246
hunderterb:
247
  MOV R22,R0        ;Rette Originalwert in R22
248
249
hunderterc:
250
  MOV R1, R21
251
  SUBI R22, 100      ;ziehe 100 ab
252
  BRLO zehnera        ;nicht mehr teilbar und raus
253
              ;(oder = prüfe Carry)
254
  INC R21          ;Erhähe Teilbar durch Zähler
255
  MOV R0,R22        ;Rette Originalwert in R0
256
  jmp hunderterc
257
258
zehnera:
259
  LDI R21,0        ;Teilerzähler erneut auf 0
260
  MOV R22,R0        ;Stelle Originalwert aus R0 her
261
  CPI R22, 10        ;Prüfe ob zehner Stelle = 0
262
  BRSH zehnerb
263
  MOV R2, R21        ;schreibe mittlere Stelle 0
264
  jmp einera
265
zehnerb:
266
  MOV R22,R0        ;Rette Originalwert in R0
267
zehnerc:
268
  MOV R2, R21        ;mittlerer Wert in R2
269
  SUBI R22, 10      ;ziehe 10 ab
270
  BRLO einera        ;nicht mehr teilbar und raus
271
              ;(oder = prüfe Carry)
272
  INC R21          ;Erhähe Teilbar durch Zähler
273
  MOV R0,R22        ;Rette Originalwert in R0
274
  jmp zehnerc
275
276
einera:  
277
  LDI R21,0        ;Teilerzähler erneut auf 0
278
  MOV R22,R0        ;Stelle Originalwert aus R0 her
279
  CPI R22, 0        ;Prüfe ob einer Stelle = 0
280
  BRNE einerb
281
  MOV R3, R21        ;schreibe vordeste Stelle 0
282
  jmp fertig
283
        
284
einerb:
285
    MOV R3,R0        ;Hole Originalwert aus R0
286
287
jmp fertigasc
288
289
290
291
292
;==================bcd2ascii=========================
293
294
fertigasc:  
295
    LDI R22, '0'  ;Lade Register 16 mit ASCII NULL
296
    ADD R1, R22    ; ASCII MSB Stelle
297
    ADD R2, R22    ;mittlere ASCII Stelle
298
    ADD R3, R22    ; ASCII LSB Stelle
299
300
    RET