1 | ;ausgangsspannungsregelung nach stepdown
|
2 | ;pwm an atmega16 für 3,906 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 OVF1addr
|
7 | ;14.2.12
|
8 | .include "m16def.inc"
|
9 |
|
10 | .def v_panel = r14 ;Messwert PV-Spannung PA0
|
11 | .def v_akku = r12 ;Messwert Akku-Spannung PA1
|
12 | .def i_panel = r10 ;Messwert PV-Strom PA2
|
13 | .def temp1 = r16 ;temporäre Variable
|
14 | ;.def wait1 = r17 ;Zähler
|
15 | ;.def wait2 = r18 ;Zähler
|
16 | .def v_akkupwm = r19 ;ermittellter Vorladewert ocr0 für 13.4v
|
17 | .def v_store = r20 ;gespeicherte Wunschspannung am PWM-Ausgang
|
18 |
|
19 |
|
20 |
|
21 | .org 0x000
|
22 | rjmp RESET ;External Pin, Power-on Reset, Brown-out
|
23 | .org INT0addr
|
24 | reti ;External Interrupt Request 0
|
25 | .org INT1
|
26 | reti ;External Interrupt Request 1
|
27 | .org OC2addr
|
28 | reti ;Timer/Counter2 Compare Match
|
29 | .org OVF2addr
|
30 | reti ;Timer/Counter2 Overflow
|
31 | .org ICP1addr
|
32 | reti ;Timer/Counter1 Capture Event
|
33 | .org OC1Aaddr
|
34 | reti ;Timer/Counter1 Compare Match A
|
35 | .org OC1Baddr
|
36 | reti ;Timer/Counter1 Compare Match B
|
37 | .org OVF1addr
|
38 | rjmp timer1ini ;TIMER1 OVF ;Timer/Counter1 Overflow
|
39 | .org OVF0addr
|
40 | rjmp timer0ini ;Timer/Counter0 Overflow
|
41 | .org SPIaddr
|
42 | reti ;Serial Transfer Complete
|
43 | .org URXCaddr
|
44 | reti ;USART, Rx Complete
|
45 | .org UDREaddr
|
46 | reti ;USART Data Register Empty
|
47 | .org UTXCaddr
|
48 | reti ;USART, Tx Complete
|
49 | .org ADCCaddr
|
50 | rjmp adini ;ADC Conversion Complete
|
51 | .org ERDYaddr
|
52 | reti ;EEPROM Ready
|
53 | .org ACIaddr
|
54 | reti ;Analog Comparator
|
55 | .org TWIaddr
|
56 | reti ;Two-wire Serial Interface
|
57 | .org INT2addr
|
58 | reti ;External Interrupt Request 2
|
59 | .org OC0addr
|
60 | reti ;Timer/Counter0 Compare Match
|
61 | .org SPMRaddr
|
62 | reti ;Store Program Memory Ready
|
63 |
|
64 | .org 0x30 ;programm ab flashadresse 30h speichern
|
65 |
|
66 | ;=============== stackpointer ini ===========================
|
67 | reset:
|
68 |
|
69 | ldi temp1, high (RAMEND)
|
70 | out SPH, temp1 ;SPH am Ende phys. SRAM
|
71 | ldi temp1, low (RAMEND)
|
72 | out SPL, temp1 ;SPL am Ende phys. SRAM
|
73 | ldi temp1,0b11111000
|
74 | out DDRA, temp1 ;pa0-2 analoge eingaenge
|
75 | ldi temp1,0b11111111
|
76 | out DDRD, temp1 ;pd2-7 ausgabe
|
77 | ldi temp1, 0b11111111
|
78 | out DDRC, temp1 ;pc0-7 ausgabe
|
79 | ldi temp1, 0b00001111
|
80 | out DDRb, temp1 ;pb0-3 ausgabe
|
81 |
|
82 | ;ldi r21, 125 ;verstärkungsfaktor fuer ad ergebniss
|
83 | ldi v_store,225 ;max.ladespannung rechner.139
|
84 | rcall timer1ini ;TIMER 1 initialisieren
|
85 | rcall timer0ini ;Timer 0 initialisieren
|
86 | rcall adini ;A-D Wandler AD0 initialisieren
|
87 |
|
88 | ;============== hauptprogramm ====================================
|
89 | main:
|
90 | rcall auswahl
|
91 |
|
92 |
|
93 |
|
94 | jmp main
|
95 | ;============== auswahl+pwm ausgabe ====================================
|
96 | auswahl:
|
97 | MOV v_akku, r18
|
98 | MOV v_akkupwm, v_akku
|
99 |
|
100 |
|
101 |
|
102 | cp v_store, v_akku ;vergleiche gespeicherte mit gemessener
|
103 | brsh up ;akkuspannung, wähle aus ob höher oder niedriger
|
104 | brlo down ;und springe zu up oder down
|
105 | jmp main
|
106 | down:
|
107 | dec v_akkupwm ;akkuspannung zu hoch, zaehle runter ;
|
108 | cp v_store, v_akkupwm ;und vergleiche mit gespeicherter spannung
|
109 | brne down ;noch nicht gleich? springe zu down
|
110 | breq sichern ;wenn gleich, sichern
|
111 | jmp main
|
112 | up:
|
113 | inc v_akkupwm
|
114 | ;cp v_store, v_akkupwm
|
115 | ;brne up
|
116 | jmp sichern
|
117 | jmp main
|
118 | sichern:
|
119 | sts 0x0072, v_akkupwm ;wert im sram gesichert, fuer spaeter
|
120 | ;mul r19,r21 ;ergebnis mit r20 verstaerken
|
121 | ;mov r19, r0 ;und in r19 verschieben
|
122 | out ocr0, v_akkupwm ;als vorladewert nach ocr0
|
123 |
|
124 | ;out ocr0,r19 ;und ins vorladeregister von tc0 gespeichert
|
125 | ; lt. simulation klappt das nicht, ich weis
|
126 | ret ;mir keinen rat warum???
|
127 |
|
128 | ;======================== timer0ini =====================
|
129 | timer0ini:
|
130 | cli
|
131 | in temp1, tccr0
|
132 | ori temp1, 0b01101010 ;tccr0, fast pwm, prescaler 8, lösche oc0 bei gleichstand
|
133 | out tccr0, temp1
|
134 | in temp1, timsk
|
135 | ori temp1, 0b00000000
|
136 | out timsk, temp1 ;ohne irq
|
137 |
|
138 | ;ldi temp1, 28 ; 255 = 13,1V
|
139 | ;out ocr0, temp1 ;gewünschte PWM-Wert 128 für 3,906 khz
|
140 |
|
141 | sei
|
142 | ret
|
143 | ;====================== ad-wandler ini =================
|
144 | adini:
|
145 | cli
|
146 | ldi temp1, (1<<REFS0)|(1<<ADLAR) ;;AREF, linkssbündig,pa0
|
147 | out ADMUX, temp1
|
148 | ldi temp1,(1<<ADEN)
|
149 | out ADCSRA,temp1 ;adcen,
|
150 | in temp1, SFIOR ;OVF1addr taktquelle für adwand
|
151 | ori temp1, (1<<ADTS2)|(1<<ADTS1)|(0<<ADTS0) ;in sfior geschrieben
|
152 | out SFIOR, temp1
|
153 | sei ;Interrupts global aktivieren
|
154 | ret
|
155 |
|
156 | ;====================== timer1ini ======================
|
157 | timer1ini:
|
158 | cli
|
159 | ldi temp1,(1<<CS11) ;Betriebsart Mode 0 (PB3 normal)
|
160 | ;4Mhz/1 Wave Form Generator Mode 0 (Normal)
|
161 | out TCCR1B, temp1 ;Prescaler 256 um bei TCNT1H + TCNT1L = 0
|
162 | in temp1, timsk ;auf ca. 239msek zu kommen
|
163 | ori temp1, (1<<TOIE1) ;Timer1 Overflow Interrupt aktiviert
|
164 | out TIMSK, temp1
|
165 | sei ;Enble all Interrupt
|
166 | ldi temp1, 0b00000000 ;Lade High Byte des 16 bit Zählers
|
167 | out TCNT1H, temp1 ;in TCNT1H
|
168 | ldi temp1, 0b00000000 ;Lade High Byte des 16 bit Zählers
|
169 | out TCNT1L, temp1 ;in TCNT1L
|
170 | sei
|
171 | ret
|
172 |
|
173 | ;======================== adwandlung pa0,1,2 ==================
|
174 | adwand:
|
175 | ;pa0
|
176 | ldi temp1,(1<<REFS0)|(1<<ADLAR) ;AVcc,linksbuendig
|
177 | out ADMUX,temp1
|
178 | ldi temp1,(1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADPS2)|(1<<ADPS1)
|
179 | out ADCSRA,temp1 ;Wandlung pa0 starten
|
180 | fertig:
|
181 | sbic ADCSRA,ADSC ;warten bis wandlung
|
182 | rjmp fertig ;beendet
|
183 |
|
184 | in temp1, ADCL ;lowbyte auslesen
|
185 | in v_panel, ADCH ;highbyte auslesen
|
186 |
|
187 | ;pa1
|
188 | ldi temp1,(1<<REFS0)|(1<<ADLAR)|(1<<MUX0) ;AVcc,linksbuendig
|
189 | out ADMUX,temp1
|
190 | ldi temp1,(1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADPS2)|(1<<ADPS1)
|
191 | out ADCSRA,temp1 ;Wandlung pa1 starten
|
192 | fertig1:
|
193 | sbic ADCSRA,ADSC ;warten bis wandlung
|
194 | rjmp fertig1 ;beendet
|
195 |
|
196 | in temp1, ADCL ;lowbyte auslesen
|
197 | in v_akku, ADCH ;highbyte auslesen
|
198 |
|
199 | ;pa2
|
200 | ldi temp1,(1<<REFS0)|(1<<ADLAR)|(1<<MUX1) ;AVcc,linksbuendig
|
201 | out ADMUX,temp1
|
202 | ldi temp1,(1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADPS2)|(1<<ADPS1)
|
203 | out ADCSRA,temp1 ;Wandlung pa2 starten
|
204 | fertig2:
|
205 | sbic ADCSRA,ADSC ;warten bis wandlung
|
206 | rjmp fertig2 ;beendet
|
207 |
|
208 | in temp1, ADCL ;lowbyte auslesen
|
209 | in i_panel, ADCH ;highbyte auslesen
|
210 |
|
211 |
|
212 |
|
213 |
|
214 | ret
|