1 | /************************LÜFTERSTEUERUNG*****************************
|
2 |
|
3 |
|
4 | ***********************************************************************/
|
5 |
|
6 | #include <avr/io.h>
|
7 | #include <avr/interrupt.h>
|
8 | //#include <util/delay.h>
|
9 | #include "TrigonometrischeFunktionen.h"
|
10 |
|
11 |
|
12 |
|
13 | /*****************************Variablen-Deklaration****************/
|
14 |
|
15 | int ALPHA = 17900;
|
16 | //int ALPHAnutz = 17900;
|
17 | volatile int ALPHAnutz = 17900;
|
18 |
|
19 | volatile int ausschaltsicherung = 0;
|
20 | volatile int netzErkannt = 0;
|
21 | volatile int drehrichtung = 0;
|
22 | volatile int frequenz = 0;
|
23 |
|
24 | int fallendeFlanke = 1; //W1
|
25 | int steigendeFlanke =1;
|
26 | volatile int zweiteHalbwelle = 0;
|
27 | volatile int weiterZuenden = 0;
|
28 | volatile int leitdauerErkennung = 0;
|
29 |
|
30 | volatile int LAMBDA = 0;
|
31 | int LAMBDAmess =0;
|
32 |
|
33 | float u = 0;
|
34 | const float uMin = 0;
|
35 | const float uMax = 1024;
|
36 | const float pi = 20000;
|
37 |
|
38 | /****************************Funktionen-Deklaration****************/
|
39 | void PortInit(void);
|
40 |
|
41 | void Timer1Init(void); //Zündverzögerung
|
42 | void Timer3Init(void); //Leitdauererfassung
|
43 | void Timer4Init(void); //Ermittlung der Periodendauer
|
44 |
|
45 | void AdcInit(void);
|
46 | void Init(void);
|
47 |
|
48 |
|
49 | float Linearisierung(volatile int LAMBDA, float u);
|
50 | int ADC_Lesen (void);
|
51 |
|
52 | /****************************Port W1 Initialisierung*****************/
|
53 |
|
54 | void PortInit(void) {
|
55 |
|
56 | DDRD=0x00; //Eingang LDE;NDG
|
57 |
|
58 | DDRC=0xFF; //Ausgang W1-Zündung
|
59 | PORTC=0xFF; //Anfangszustand; lowactic
|
60 |
|
61 | DDRF=0x00; //Eingang AD-Konverter
|
62 |
|
63 | DDRB=0xFF; //Ausgang
|
64 | PORTB=0x00;
|
65 | }
|
66 |
|
67 | /****************************TIMER1-Initialisierung*****************/
|
68 |
|
69 | void Timer1Init(void) //Zündverzögerung
|
70 | {
|
71 | TCCR1B = 0x00; //stop Timer
|
72 | TCCR1A = 0x00; //normaler Modus = inkrementale Aufzählung
|
73 |
|
74 | TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B);// | (1<<OCIE1C); //Interrupts aktivieren für: compare Register A B C
|
75 |
|
76 | EIMSK |= (1<<INT0); //aktiviere INT0
|
77 | // EICRA |= (1<<ISC01); //INT0 reagiert auf fallende Flanke
|
78 | EICRA |= (0<<ISC01) | (1<<ISC00); //INT0 reagiert auf fallende und steigende Flanke
|
79 | TCCR1B = 0x02; //Vorteiler 8; start Timer1 bei 0
|
80 | }
|
81 |
|
82 |
|
83 | /****************************TIMER4-Initialisierung*****************/
|
84 |
|
85 | void Timer4Init(void) //Ermittlung der Periodendauer
|
86 | {
|
87 | TCCR4B = 0x00; //stop Timer
|
88 | TCCR4A = 0x00; //normaler Modus = inkrementale Aufzählung
|
89 | TCCR4B = 0x02; //Vorteiler 8; start Timer4 bei 0
|
90 | EICRA |= (1<<ISC11)| (1<<ISC10); //Reagiert auf Steigende Flanke
|
91 |
|
92 | EIMSK |= (1<<INT1);
|
93 | }
|
94 | /****************************Hauptprogramm*****************/
|
95 | int main()
|
96 | {
|
97 |
|
98 | int linearisierungsBeschraenkung = 20;
|
99 |
|
100 |
|
101 | cli(); //disable Interrupts
|
102 | Init();
|
103 | sei(); //alles initialisiert
|
104 | //enable Interrupts
|
105 |
|
106 | while(1)
|
107 | {
|
108 |
|
109 | u = (((uMax - uMin) / (1023)) * (ADC_Lesen()) + uMin);
|
110 |
|
111 |
|
112 | if(linearisierungsBeschraenkung >= 20) //alle 20 main-Durchläufe wird hier rein gesprungen
|
113 | {
|
114 | linearisierungsBeschraenkung = 0;
|
115 | ALPHA = Linearisierung(LAMBDA, u);// - 480; //ACHTUNG! Dieser Korrekturfaktor ist nur für die ALTE Schaltung!
|
116 |
|
117 |
|
118 | }
|
119 | linearisierungsBeschraenkung++;
|
120 | }
|
121 | }
|
122 |
|
123 | /******************************EXTERNER Interrupt*****************/
|
124 |
|
125 | /*Netzsynchronisierung*/
|
126 | ISR (INT0_vect) //NDG; 240us Verzögerung
|
127 | {
|
128 | TCNT1=0;
|
129 | TCNT4=0;
|
130 | //OCR1A = ALPHA;
|
131 | steigendeFlanke=1;
|
132 |
|
133 | ALPHAnutz = ALPHA;
|
134 | OCR1A = ALPHAnutz;
|
135 |
|
136 | }
|
137 |
|
138 | ISR (INT1_vect)
|
139 | {
|
140 | LAMBDAmess =TCNT4;
|
141 |
|
142 | if ((LAMBDAmess >=1000) && (LAMBDAmess <19000))
|
143 | {
|
144 | LAMBDA=LAMBDAmess;
|
145 | }
|
146 | }
|
147 | /******************************SOFTWARE Interrupts****************/
|
148 |
|
149 | ISR (TIMER1_COMPA_vect) //Zündung erste Halbwelle
|
150 | {
|
151 | PORTC &= ~(1<<PC0); //T1 AN W1 Low Aktiv
|
152 | OCR1B = ALPHAnutz + 400; //ALPHAnutz + Zuendimpulsbreite;
|
153 | }
|
154 |
|
155 | ISR (TIMER1_COMPB_vect) //Löschen aller gezündeten Pins
|
156 | {
|
157 | PORTC |= (1<<PC0); //T1 aus W1 Low Aktiv
|
158 | //OCR1A = ALPHA;
|
159 | }
|
160 |
|
161 | /****************************Funktionen************************/
|
162 |
|
163 | /*Linearisierung*/
|
164 | float Linearisierung(volatile int LAMBDA, volatile float u)
|
165 | {
|
166 |
|
167 | int result =0;
|
168 | float Pi = 3.14159;
|
169 | float lambda =LAMBDA *0.009*Pi/180; //Takte in RAD
|
170 | float SINUSVonMinusLAMBDA = (-Sinus(LAMBDA));
|
171 |
|
172 |
|
173 | float relativ_u = u/uMax;
|
174 | float relativ_uQuadrat = relativ_u*relativ_u;
|
175 |
|
176 | float Term1 = relativ_uQuadrat*Pi;
|
177 |
|
178 | float Term2 = Term1-lambda;
|
179 | float Term3 = SINUSVonMinusLAMBDA/10000; //der Wert aus der inustabelle muss durch 10.000 geteilt werden
|
180 |
|
181 | float Bruch = (Term2/Term3)*10000; //Argument für den Arccos //Arccosinus nimmt nur Takte entgegen
|
182 |
|
183 | float ArcCosinusVonBruch = 0;
|
184 | ArcCosinusVonBruch = (float)ArcCosinus((float)Bruch);
|
185 |
|
186 | float Term4 =ArcCosinusVonBruch/10000; //Von Takte in Radiant Zurückrechnen
|
187 |
|
188 | float Term5=2*Pi-Term4;
|
189 |
|
190 | float Term6 = Term5 - lambda;
|
191 | float Term7 = Term6/2; //ergebnis in Rad
|
192 |
|
193 | float Term8 = Term7*180/Pi;
|
194 | float Term9 = Term8*111.11; //Alpha in Takten
|
195 |
|
196 | float z = (Term9*2)+LAMBDA;//Sinus Argument
|
197 |
|
198 | //Bereichsabfrage des Sinus Argumentes
|
199 | if ((z)>1 & (z)<30000)
|
200 | {
|
201 | float Term_5=0;
|
202 | Term_5 = Pi+Term4;
|
203 |
|
204 | float Term_6 = 0;
|
205 | Term_6 = Term_5 - lambda;
|
206 |
|
207 | float Term_7 = 0;
|
208 | Term_7= Term_6/2; //ergebnis in Rad
|
209 |
|
210 | float Term_8 = 0;
|
211 | Term_8=Term_7*180/Pi;
|
212 |
|
213 | float Term_9 = 0;
|
214 | Term_9=Term_8*111.11; //Alpha ;
|
215 |
|
216 | result = Term_9;
|
217 | return result;
|
218 |
|
219 | }
|
220 | else if ((z)>=30000 & (z) <=40000)
|
221 | {
|
222 | result = Term9;
|
223 | return result;
|
224 | }
|
225 |
|
226 | else if ((z)>40000 & (z) <=50000)
|
227 | {
|
228 | float Term_52=0;
|
229 | Term_52 = 2*Pi+Term4;
|
230 | float Term_62 = 0;
|
231 | Term_62 = Term_52 - lambda;
|
232 | float Term_72 = 0;
|
233 | Term_72= Term_62/2; //ergebnis in Rad
|
234 |
|
235 | float Term_82 = 0;
|
236 | Term_82=Term_72*180/Pi;
|
237 | float Term_92 = 0;
|
238 | Term_92=Term_82*111.11; //Alpha ;
|
239 | result = Term_92;
|
240 | return result;
|
241 | }
|
242 |
|
243 |
|
244 | }
|
245 |
|
246 |
|
247 |
|
248 | /***************************************ADC W1**********************/
|
249 | void AdcInit (void)
|
250 | {
|
251 | ADMUX |= (0<<MUX0) | (0<<MUX1) | (0<<MUX2); //ADC0
|
252 | ADMUX |= (1<<REFS0); //externe Referenzspannung nutzen 5 V
|
253 | ADCSRA |=(1<<ADEN); //ADC überhaupt zu aktivieren.
|
254 | ADMUX |= (0<< ADLAR); // Die 8 bit kommen in das Low-Register
|
255 | ADCSRA |=(1<<ADSC); //Messvorgang startet.
|
256 | ADCSRA |=(1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);//Vorteiler 128
|
257 | }
|
258 |
|
259 |
|
260 | int ADC_Lesen (void)
|
261 | {
|
262 | ADCSRA |=(1<<ADEN); //ADC aktivieren.
|
263 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
264 | while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
|
265 |
|
266 | ADCSRA &= ~(1<<ADEN); // ADC wieder deaktivieren
|
267 | return ADCW;
|
268 | }
|
269 |
|
270 |
|
271 | //********************************INITIALISIERUNG*******************
|
272 | void Init()
|
273 | {
|
274 |
|
275 | PortInit();
|
276 |
|
277 | Timer1Init();
|
278 | // Timer3Init();
|
279 | Timer4Init();
|
280 | PORTB |= (1<<PINB3); //rote LED aus
|
281 | PORTB |=(1<<PINB3); //rote LED aus
|
282 | AdcInit();
|
283 | }
|