1 | /*
|
2 | * P16081220.c
|
3 | * V3.0
|
4 | * Created: 16.08.2012 15:40:40
|
5 | * Author: Alberto Vazquez
|
6 | *
|
7 | *edit by: Fabian Binder
|
8 | *date: 27.05.2014
|
9 | */
|
10 |
|
11 |
|
12 | /***********************************************************************************************
|
13 | Inclusion of necessary libraries
|
14 | ***********************************************************************************************/
|
15 | #include <avr/io.h>
|
16 | #include "konst.h"
|
17 |
|
18 | /***********************************************************************************************
|
19 | Inclusion of global variables
|
20 | ***********************************************************************************************/
|
21 | volatile flag TIM_OVR = FALSE, ADC_OVR = FALSE, SCR_FR = TRUE; //, CAPT_OVR = FALSE
|
22 | volatile flag SRN_BLK = FALSE, SYS_BLK = TRUE, SYS_BYPASS = FALSE;
|
23 | volatile uint16_t Count;
|
24 |
|
25 | /***********************************************************************************************
|
26 | Main Function
|
27 | ***********************************************************************************************/
|
28 | int main(void)
|
29 | {
|
30 | zbuff buff_tank, buff_oel,buff_temp;
|
31 | sts Tank_st = DSCND, Oel_st = DSCND;
|
32 | flag Tank_fr = TRUE, Temp_fr = TRUE, Ini_ovr = FALSE;
|
33 | uint16_t adc_prev, adc_next, IniAbst; //, tim_prev, tim_next
|
34 | uint16_t tank_sum = 0, oel_sum = 0, tank_prom = 0, oel_prom = 0;
|
35 | uint16_t oel_prom_akt = 0, oel_prom_prev = 0, oel_prom_next = 0;
|
36 | uint16_t temp_sum = 0, temp_prom = 0;
|
37 | int16_t tank_aux;
|
38 | int8_t oel_derv;
|
39 | uint8_t temp, temp_p = 0,temp_p2 = 0,temp_p3 = 0, temp_a;
|
40 | kont dataok, dervkont = 3, dervdelay = DDELAY, tank_err = TTRHLD;
|
41 | kont oeldelay = ODELAY, tankdelay = TDELAY, toggledelay = TGGLD, tempdelay = 1;
|
42 |
|
43 | sys_ini();
|
44 | zbuff_ini(&buff_tank);
|
45 | zbuff_ini(&buff_oel);
|
46 | zbuff_ini(&buff_temp);
|
47 |
|
48 | while(TRUE)
|
49 | {
|
50 | //Timer_reset();
|
51 | //Timer_ena();
|
52 | //Ena_Burst();
|
53 | ADC_Selec(0);
|
54 | ADC_Start_C();
|
55 | //tim_next = 0xFFFF;
|
56 | dataok = 3;
|
57 | --tempdelay;
|
58 |
|
59 | /************** DATA CAPTURE **************************************************/
|
60 | while(dataok){
|
61 |
|
62 | if(ADC_OVR){
|
63 | adc_next = ADC;
|
64 |
|
65 | if(!(ADMUX & 0x0F)){
|
66 | if(buff_oel.status == VOLL){
|
67 | zbuff_pop(&buff_oel,&adc_prev);
|
68 | zbuff_push(&buff_oel,adc_next);
|
69 | oel_sum += adc_next - adc_prev;
|
70 | oel_prom = divf_base2(oel_sum,SHIFT);
|
71 | }
|
72 |
|
73 | else{
|
74 | zbuff_push(&buff_oel,adc_next);
|
75 | if(buff_oel.status == VOLL)
|
76 | oel_sum = add_array(buff_oel);
|
77 | }
|
78 | ADC_Selec(1);
|
79 | ADC_Start_C();
|
80 | }
|
81 |
|
82 | else if((ADMUX & 0x0F) == 1){ //Änderung: von Timer zu ADC
|
83 | if(buff_tank.status == VOLL){
|
84 | zbuff_pop(&buff_tank,&adc_prev);
|
85 | zbuff_push(&buff_tank,adc_next);
|
86 | tank_sum += adc_next - adc_prev;
|
87 | tank_prom = divf_base2(tank_sum,SHIFT);
|
88 | }
|
89 | else{
|
90 | zbuff_push(&buff_tank,adc_next);
|
91 | if(buff_tank.status == VOLL)
|
92 | tank_sum = add_array(buff_tank);
|
93 | }
|
94 | ADC_Selec(2);
|
95 | ADC_Start_C();
|
96 | }
|
97 |
|
98 | else if((ADMUX & 0x0F) == 2){
|
99 | if(buff_temp.status == VOLL){
|
100 | zbuff_pop(&buff_temp,&adc_prev);
|
101 | zbuff_push(&buff_temp,adc_next);
|
102 | temp_sum += adc_next - adc_prev;
|
103 | temp_prom = divf_base2(temp_sum,SHIFT);
|
104 | }
|
105 |
|
106 | else{
|
107 | zbuff_push(&buff_temp,adc_next);
|
108 | if(buff_temp.status == VOLL)
|
109 | temp_sum = add_array(buff_temp);
|
110 | }
|
111 | }
|
112 |
|
113 | --dataok;
|
114 | ADC_OVR = FALSE;
|
115 | }
|
116 |
|
117 |
|
118 | // if(CAPT_OVR){ //////////////////////////////////////////////////////////////////////////
|
119 | // tim_next = Count - OVRTIM; //OVRTIM=Overflow von timer1: Wert=(5536+10000) wird von Count abgezogen//
|
120 | // CAPT_OVR = FALSE; //////////////////////////////////////////////////////////////////////////
|
121 | // }
|
122 |
|
123 | /*if(TIM_OVR){
|
124 |
|
125 | if(buff_tank.status == VOLL){
|
126 | zbuff_pop(&buff_tank,&tim_prev);
|
127 | zbuff_push(&buff_tank,tim_next); ///////////////////////////////////////////////////////////////////////////////////////////////////////
|
128 | tank_sum += tim_next - tim_prev; //tank_sum += tim_prev - tim_next; --> ?? eventuell Änderung noptwendig///////////////////////////////
|
129 | tank_prom = divf_base2(tank_sum,SHIFT); //tank_prom = tank_sum/2^Shift; (Shift=4;siehe calc.h) es gilt wenn tank_prom<.....,5 wird abgerundet//
|
130 | } //////////////////////////////////falls tank_prom>.....,5 wird aufgerundet/////////////////////////////
|
131 | else{ ///////////////////////////////////////////////////////////////////////////////////////////////////////
|
132 | zbuff_push(&buff_tank,tim_next);
|
133 | if(buff_tank.status == VOLL)
|
134 | tank_sum = add_array(buff_tank);
|
135 | }
|
136 |
|
137 | --dataok;
|
138 | TIM_OVR = FALSE;
|
139 | }*/
|
140 | }
|
141 |
|
142 | temp_a = (uint8_t)(divf_base2((divf_base2((temp_prom * 25),4) * 5),4)); //statt 4 stand SHIFT
|
143 | /******************** DATA EVALUATION ******************************************/
|
144 | if(!SYS_BYPASS){
|
145 | if(Ini_ovr){
|
146 | if(!SYS_BLK){
|
147 |
|
148 | //Tank sensor routine //////////////////////////////////////////////////////////
|
149 | if ((tank_prom > LADCL) && (tank_prom < MAXADC)){ //Zeitliche Begrenzung zur Aktivierung der Sensorroutine//if ((tank_prom > LADCL) && (tank_prom < MINDST)){
|
150 | //////////////////////////////////////////////////////////
|
151 |
|
152 | if(tankdelay)
|
153 | --tankdelay;
|
154 |
|
155 | else{
|
156 | if(Tank_fr){ ///////////////////////////////////
|
157 | IniAbst = 0xFFFF; //Ultraschall: IniAbst = 0xFFFF;//
|
158 | Tank_fr = FALSE; /////////////////////////////////
|
159 | }
|
160 | //////////////////////////////////////////////////////////
|
161 | if(tank_prom < IniAbst) //if(tank_prom > IniAbst)/////////////////////////////////
|
162 | IniAbst = tank_prom; //IniAbst = tank_prom;////////////////////////////////////
|
163 | //////////////////////////////////////////////////////////
|
164 | tank_aux = tank_prom - IniAbst; //Ultraschall: tank_aux = tank_prom - IniAbst;/////////////////////////
|
165 | //////////////////////////////////////////////////////////
|
166 | if((tank_aux >= ERRDST) || (tank_prom >= MINDST)) //Alarmauslösung nur in einem bestimmten Bereich möglich// (tank_aux < 0x8000) && (tank_aux > LIMTKH)
|
167 | --tank_err; //////////////////////////////////////////////////////////
|
168 |
|
169 | else
|
170 | tank_err = TTRHLD;
|
171 |
|
172 |
|
173 |
|
174 | //Verify the difference between the initial value
|
175 | //of the tank and the actual
|
176 | if(!tank_err){
|
177 | SRN_BLK = FALSE;
|
178 | Tank_st = ERROR;
|
179 | SYS_BLK = TRUE;
|
180 | Tank_fr = TRUE;
|
181 | Stop_bank();
|
182 | PWM_ch1_stop();
|
183 | PWM_ch2_on();
|
184 | tank_err = TTRHLD;
|
185 | Clear_INT0();
|
186 | Enable_INT0();
|
187 | }
|
188 |
|
189 | //In other cases the system is OK
|
190 | else {
|
191 | SRN_BLK &= (Tank_st == SNSOK) ? TRUE : FALSE;
|
192 |
|
193 | if((Oel_st == SNSOK) && (Tank_st != SNSOK)) { //if((Oel_st == SNSOK) && (Tank_st != SNSOK)) {
|
194 | Enable_bank();
|
195 | PWM_ch2_stop();
|
196 | }
|
197 | if(Oel_st != ERROR) //Zeile hinzugefügt
|
198 | PWM_ch1_on();
|
199 | Tank_st = SNSOK;
|
200 | }
|
201 | }
|
202 | }
|
203 |
|
204 | //Verify if the sensor is connected
|
205 | /*if((!(PINB && (1<<PINB0))) || (tank_prom > LTIMH)){
|
206 | SRN_BLK &= (Tank_st == DSCND) ? TRUE : FALSE;
|
207 |
|
208 | if(Tank_st != DSCND){
|
209 | PWM_ch2_on();
|
210 | Tank_fr = TRUE;
|
211 | dervkont = 3;
|
212 | Ini_ovr = FALSE;
|
213 | SYS_BLK = TRUE;
|
214 | Stop_bank();
|
215 | tankdelay = TDELAY;
|
216 | }
|
217 |
|
218 | PWM_ch1_on();
|
219 | Tank_st = DSCND;
|
220 | }*/
|
221 | if(tank_prom <= MAXDST){
|
222 | SRN_BLK &= (Tank_st == DSCND) ? TRUE : FALSE;
|
223 |
|
224 | if(Tank_st != DSCND){
|
225 | PWM_ch2_on();
|
226 | Tank_fr = TRUE;
|
227 | dervkont = 3;
|
228 | Ini_ovr = FALSE;
|
229 | SYS_BLK = TRUE;
|
230 | Stop_bank();
|
231 | tankdelay = TDELAY;
|
232 | }
|
233 |
|
234 | PWM_ch1_on();
|
235 | Tank_st = DSCND;
|
236 | }
|
237 |
|
238 | //Oilmist sensor routine
|
239 | if (oel_prom > LADCL){
|
240 |
|
241 | --dervdelay;
|
242 |
|
243 | if(!dervdelay){
|
244 | if(!dervkont)
|
245 | oel_derv = (int8_t)(((uint8_t)oel_prom_next) - ((uint8_t)oel_prom_prev));
|
246 |
|
247 | else
|
248 | --dervkont;
|
249 |
|
250 | oel_prom_prev = oel_prom_akt;
|
251 | oel_prom_akt = oel_prom_next;
|
252 | oel_prom_next = oel_prom;
|
253 | dervdelay = DDELAY;
|
254 | }
|
255 |
|
256 | //Verify error in the derivate signal of the oil mist
|
257 | if ((oel_derv > LIMDH) && (oel_derv < 0x80)){
|
258 | SRN_BLK = FALSE;
|
259 | Oel_st = ERROR;
|
260 | SYS_BLK = TRUE;
|
261 | dervkont = 3;
|
262 | oel_derv = 0;
|
263 | Stop_bank();
|
264 | PWM_ch1_stop();
|
265 | PWM_ch2_on();
|
266 | Clear_INT0();
|
267 | Enable_INT0();
|
268 | }
|
269 |
|
270 | //Verify error in the signal of the oil mist (security redundancy)
|
271 | else if((oel_prom >= LIMOELH)){
|
272 | SRN_BLK = FALSE;
|
273 | Oel_st = ERROR;
|
274 | SYS_BLK = TRUE;
|
275 | dervkont = 3;
|
276 | Stop_bank();
|
277 | PWM_ch1_stop();
|
278 | PWM_ch2_on();
|
279 | Clear_INT0();
|
280 | Enable_INT0();
|
281 | }
|
282 |
|
283 | //Other cases the system is OK
|
284 | else {
|
285 | SRN_BLK &= (Oel_st == SNSOK) ? TRUE : FALSE;
|
286 |
|
287 | if((Tank_st == SNSOK) && (Oel_st != SNSOK)){
|
288 | Enable_bank();
|
289 | PWM_ch2_stop();
|
290 | }
|
291 | if(Tank_st != ERROR)
|
292 | PWM_ch1_on();
|
293 | Oel_st = SNSOK;
|
294 | }
|
295 | }
|
296 |
|
297 | //Verify if the sensor is connected
|
298 | else if (oel_prom <= LADCL){
|
299 | SRN_BLK &= (Oel_st == DSCND) ? TRUE : FALSE;
|
300 |
|
301 | if((Tank_st != ERROR) && (Oel_st != DSCND)){
|
302 | PWM_ch2_on();
|
303 | PWM_ch1_on();
|
304 | Stop_bank();
|
305 | Ini_ovr = FALSE;
|
306 | SYS_BLK = TRUE;
|
307 | Tank_fr = TRUE;
|
308 | tankdelay = TDELAY;
|
309 | dervkont = 3;
|
310 | }
|
311 |
|
312 | Oel_st = DSCND;
|
313 | }
|
314 | }
|
315 | }
|
316 |
|
317 | //Check status of sensors during initialization
|
318 | else{
|
319 | --toggledelay;
|
320 |
|
321 | if(!toggledelay){
|
322 | toggledelay = TGGLD;
|
323 | PWM_ch2_tggl();
|
324 | }
|
325 |
|
326 | /*if((!(PINB && (1<<PINB0))) || (tank_prom > LTIMH)){ //Init-Abfrage geändert
|
327 | SRN_BLK &= (Tank_st == DSCND) ? TRUE : FALSE;
|
328 | Tank_st = DSCND;
|
329 | }
|
330 |
|
331 | else if ((tank_prom > LTIML) && (tank_prom < LTIMH)){
|
332 | SRN_BLK &= (Tank_st == SNSOK) ? TRUE : FALSE;
|
333 | Tank_st = SNSOK;
|
334 | }*/
|
335 | if ((tank_prom <= LADCL) || (tank_prom >= MAXADC)){ //Geänderte Init-Abfrage (gleich der Öl Ini)
|
336 | SRN_BLK &= (Tank_st == DSCND) ? TRUE : FALSE; //Muss eventuell nochmal geändert werden da Tank Sensor nur mit Ölsensor "ok" einen "err" bringt
|
337 | tankdelay = TDELAY;
|
338 | Tank_st = DSCND;
|
339 | }
|
340 |
|
341 | else if((tank_prom > LADCL) && (tank_prom < (MAXADC-1))){
|
342 |
|
343 | if(tankdelay) //Abfrage wieder rückgängig machen aber mit anderen Grenzen
|
344 | --tankdelay;
|
345 |
|
346 | else{
|
347 | SRN_BLK &= (Tank_st == SNSOK) ? TRUE : FALSE;
|
348 | Tank_st = SNSOK;
|
349 | }
|
350 | }
|
351 |
|
352 | if ((oel_prom <= LADCL) || (oel_prom >= LADCH)){
|
353 | SRN_BLK &= (Oel_st == DSCND) ? TRUE : FALSE;
|
354 | oeldelay = ODELAY;
|
355 | Oel_st = DSCND;
|
356 | }
|
357 |
|
358 | else if((oel_prom > LADCL) && (oel_prom < LADCH)){
|
359 |
|
360 | if(oeldelay)
|
361 | --oeldelay;
|
362 |
|
363 | else{
|
364 | SRN_BLK &= (Oel_st == SNSOK) ? TRUE : FALSE;
|
365 | Oel_st = SNSOK;
|
366 | }
|
367 | }
|
368 |
|
369 | if(Tank_st == SNSOK && Oel_st == SNSOK){
|
370 | PWM_ch2_stop();
|
371 | Ini_ovr = TRUE; //Erst wenn Tank UND Oel OK sind geht das Programm weiter in die Fehlerabfrage
|
372 | SYS_BLK = FALSE;
|
373 | Enable_bank();
|
374 | }
|
375 | }
|
376 | }
|
377 |
|
378 | else{
|
379 | Ini_ovr = FALSE;
|
380 | SYS_BLK = TRUE;
|
381 | dervkont = 3;
|
382 | Tank_fr = TRUE;
|
383 | tankdelay = TDELAY;
|
384 | }
|
385 | /******************** SCREEN REFRESH ******************************************/
|
386 | if(SCR_FR){
|
387 | LCD_Clear();
|
388 | LCD_Tank();
|
389 | LCD_GOTO2ADD(0x09);
|
390 | LCD_Oel();
|
391 | LCD_GOTO2ADD(GOTO_SL);
|
392 | LCD_Temp();
|
393 | SCR_FR = FALSE;
|
394 | }
|
395 |
|
396 |
|
397 | if(!SRN_BLK){
|
398 |
|
399 | if(!SYS_BYPASS){
|
400 | LCD_GOTO2ADD(0x05);
|
401 | switch(Tank_st){
|
402 | case SNSOK:
|
403 | LCD_OK();
|
404 | break;
|
405 | case DSCND:
|
406 | LCD_AUS();
|
407 | break;
|
408 | case ERROR:
|
409 | LCD_ERR();
|
410 | break;
|
411 | default:
|
412 | break;
|
413 | }
|
414 |
|
415 | LCD_GOTO2ADD(0x0C);
|
416 | switch(Oel_st){
|
417 | case SNSOK:
|
418 | LCD_OK();
|
419 | break;
|
420 | case DSCND:
|
421 | LCD_AUS();
|
422 | break;
|
423 | case ERROR:
|
424 | LCD_ERR();
|
425 | break;
|
426 | default:
|
427 | break;
|
428 | }
|
429 | }
|
430 |
|
431 | else{
|
432 | LCD_GOTO2ADD(GOTO_FL);
|
433 | LCD_SB();
|
434 | }
|
435 |
|
436 | SRN_BLK = TRUE;
|
437 | }
|
438 |
|
439 | if(!tempdelay){
|
440 | tempdelay = RFHTEMP;
|
441 | temp = divf_base2((temp_a + temp_p + temp_p2 + temp_p3),2);
|
442 | temp_p3 = temp_p2;
|
443 | temp_p2 = temp_p;
|
444 | temp_p = temp_a;
|
445 | LCD_GOTO2ADD(0x45);
|
446 |
|
447 | if((temp < LHTEMP) && !Temp_fr)
|
448 | LCD_printnum(temp);
|
449 |
|
450 | else
|
451 | LCD_AUS2();
|
452 |
|
453 | if(Temp_fr){
|
454 | Temp_fr = FALSE;
|
455 | PWM_ch3_on();
|
456 | }
|
457 | }
|
458 |
|
459 | /**********************************************************************************************/
|
460 |
|
461 | }
|
462 | }
|
463 |
|
464 | /***********************************************************************************************
|
465 | Interruption Verctors
|
466 | ***********************************************************************************************/
|
467 | //Called when is the timer reaches the comp. value of the timer1
|
468 | //ISR (TIMER1_COMPA_vect){ //burst ist kein ausgang mehr
|
469 | // Dis_Burst(); //da PortC1 als ADC verwendet wird
|
470 | // T1_Clear_Flag();
|
471 | // T1IC_Ena_Int();
|
472 | //}
|
473 |
|
474 | //Called when there is a overflow of the timer1
|
475 | //ISR (TIMER1_OVF_vect){
|
476 | // Timer_stop();
|
477 | // TIM_OVR = TRUE;
|
478 | //}
|
479 |
|
480 | //Called when there is a negative edge on the pin PB0 (#14)
|
481 | //ISR (TIMER1_CAPT_vect){ ///////////////////////////////////////////////////////////
|
482 | // Count = ICR1; //Aktueller Zählstand wird über ICR1 in Count gespeichert//
|
483 | // T1IC_Dis_Int(); ///////////////////////////////////////////////////////////
|
484 | // CAPT_OVR = TRUE;
|
485 | //}
|
486 |
|
487 | //Called when the ADC finishes the convertion
|
488 | ISR (ADC_vect){
|
489 | ADC_OVR = TRUE;
|
490 | }
|
491 |
|
492 | //Called when there is a negative edge on the pin PD2 (#4)
|
493 | ISR (INT0_vect){
|
494 | Disable_INT0();
|
495 | SRN_BLK = FALSE;
|
496 | SYS_BLK = FALSE;
|
497 | }
|
498 |
|
499 | //Called when the uart's buffer is full (Data received)
|
500 | ISR (USART_RX_vect){
|
501 | uint8_t temp = UDR0;
|
502 |
|
503 | if(temp == BLK && !SYS_BYPASS){
|
504 | SYS_BYPASS = TRUE;
|
505 | SRN_BLK = FALSE;
|
506 | PWM_ch1_stop();
|
507 | PWM_ch2_stop();
|
508 | Enable_bank();
|
509 | uart_send(BLKRSP);
|
510 | }
|
511 |
|
512 | else if(temp == UBLK && SYS_BYPASS){
|
513 | SYS_BYPASS = FALSE;
|
514 | SCR_FR = TRUE;
|
515 | SRN_BLK = FALSE;
|
516 | PWM_ch1_on();
|
517 | PWM_ch2_on();
|
518 | uart_send(UBLKRSP);
|
519 | }
|
520 | }
|