Rev Author Line No. Line
797 mija 1 #include <16F876A.h>
2 #device adc=10
3  
4 #FUSES NOWDT //No Watch Dog Timer
5 #FUSES NOLVP,NOPROTECT,XT,NOBROWNOUT
6 #use delay(clock=4000000)
7 //#define EEPROM_SCL PIN_C3
8 //#define EEPROM_SDA PIN_C4
9 #use rs232(baud=9600,xmit=PIN_C6,disable_ints)
10 //#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
11  
12  
13 #define LCD_RS PIN_C7 // rizeni registru LCD displeje <lcd.c>
14 #define LCD_E PIN_B7 // enable LCD displeje <lcd.c>
15 #define LCD_D0 PIN_B3 // data LCD <lcd.c>
16 #define LCD_D1 PIN_B2
17 #define LCD_D2 PIN_B1
18 #define LCD_D3 PIN_B0
19 #define PWM_OUT PIN_C2 // kontrast LCD - menic
20 #define LCD_ENABLE PIN_A1
21  
22 #define GM_PIN PIN_A4 // vstup od GMT
23 #define HV_ENABLE PIN_A3 // start 400V
24 #define CHARGE PIN_A2 // nabijeni baterie
25  
26 #define KBD_K4 0 //tlacitko na PIN_B7 neexistuje <kbd.c>
27 #define TL3 0x10 //tlacitko PIN_B4 -ostatni default, viz <kbd.c>
28 #define TL2 0x20 //tlacitko PIN_B5 <kbd.c>
29 #define TL1 0x40 //tlacitko PIN_B6 <kbd.c>
30  
31 #define KBD_CALMTIME 1 //x*40ms - doba na zakmity tlacitek <kbd.c>
32 #define KEYDELAY 30 //x*40ms - doba podrzeni tlacitka do opakovani
33 #define KEYREPEAT 6 //x*40ms - doba opakovani stiskleho tlacitka
34 #define LOG_PERIOD 30 //perioda logovani v min
35 #define TIME_TO_SLEEP 19 //x*16s - doba do uspani, pokud zadny stisk a HV nebezi
36  
37 #define MAX_EEPROM 255 //max velikost vnitrni ee pameti
38 #define EE_LOG_SWITCH 1 //misto v ee, kam se uklada zpusob logovani
39 #define EE_LOG_OFFSET 0 //misto v ee, kde je ulozen offset dalsiho volneho mista
40  
41 #define ECHO_MAX_CYCLE 700 //ryhlost hlavni smyèky za 40ms /cca 20kHz/ (700)
42 #define ECHO_PIN1 PIN_C4 //piezo
43 #define ECHO_PIN2 PIN_C5 //piezo
44  
45 #define TEST_V_BATT 0x0f //maska minut pro test baterie
46 #define BATT_ENABLE 525 //1024/ADC*1.5+0.18 ADC=525 .. Ubat=3.1V; jeli Ubat nizsi pak sleep
47  
48 #include <lcd.c>
49 #include <kbd.c>
50  
51 int8 ms7RTC,sRTC,mRTC,hRTC,dRTC,mdRTC,yRTC; //promenne RTC
52 int1 vypocet,refresh,counters,sleep,log,piezo; //povoleni vypoctu,zobrazeni,citani,uspani,logovani,cvak pieza
53 int16 avg,bkg,min,max,dif; //hlavni zobrazované promìnne
54 int32 gmcount,mincount; //citac trubice GM,citac minut od startu
55 int8 timer_n,timer_s; //citace pulzù do 40ms, v celych 40ms, v predchozi 40ms
56 int32 gmcount_p; //pocet pulzu od zapnuti v predchozi cele minute
57 int32 gmcount_sm; //pocet pulzu od zapnuti precteno v cele minute
58 int8 s25tik,sTIK; //tiky pro casovani trubice 25tiku do sekundy, 60s do min
59 int8 key_timer,save_key,keyp; //pomocny citac pro tlacitka,ulozeni stiskleho tlacitka,provedeni akce stiskleho tl.
60 int8 menu_A,menu_B; //vektor pro pohyb v menu na LCD
61 int8 log_interval; //minutovy citac do dalsiho logu
62 int8 log_switch; //prepinac zpusobu logovani
63 int8 ee_offset; //kam v ee ulozit dalsi zaznam
64 int8 echo_switch,echo_tik; //povolení echa,poèet tiku za 40ms
65 int16 echo_timer,echo_cycle; //èitaè rychlosti smyèky pro echo,cvaknuti v cyklu
66 int8 pwm; //kontrast
67 int8 tik_to_sleep; //casovac pro uspani
68 float analog; //napeti baterie
69 int1 test_batt; //test napeti baterie
70 int1 test; //pokus
71 int8 timertest; //pokus
72  
73 #priority timer2,timer1,rb
74  
75 #int_TIMER2 //nastaven presne na 40ms,cte casovac timer0 GMT
76 TIMER2_isr()
77 {
78 kbd_ticktimer();
79 if (key_timer) key_timer--;
80 if (!counters) {set_timer0(0);s25TIK=0;sTIK=0;return;}
81 if (echo_switch) echo_switch=2;
82 timer_n=get_timer0();
83 s25TIK++;
84 if (timer_n!=timer_s) //nastala zmena v citaci,pak proved pricteni puslu
85 {
86 if (timer_n < timer_s) {timer_s=256-timer_s+timer_n;gmcount=gmcount+timer_s;} //test preteceni casovace
87 else {timer_s=timer_n-timer_s;gmcount=gmcount+timer_s;}
88 echo_tik=timer_s;
89 timer_s=timer_n;
90 if (menu_A==1 && menu_B==0) refresh=true;
91 }
92 else echo_tik=0;
93 if (s25TIK==25) //cela sekunda
94 {
95 s25TIK=0;
96 sTIK++;
97 if (menu_A==1 && menu_B==5) refresh=true;
98 if (sTIK==60) //cela minuta
99 {
100 sTIK=0;
101 mincount++;
102 vypocet=true;
103 gmcount_sm=gmcount;
104 }
105 }
106 }
107  
108 #int_RB
109 RB_isr()
110 {
111 kbd_pullkbd();
112 tik_to_sleep = TIME_TO_SLEEP;
113 }
114  
115 int8 modulo(int8 h,int8 m) //pomocna fce pro modulo x
116 {
117 if (h<m) return (h);
118 return(h-m);
119 }
120  
121 void clear_lcd()
122 {
123 printf(lcd_putc,"\f");
124 }
125  
126 void set_date() //citac datumu
127 {
128 dRTC++;
129 switch (mdRTC)
130 {
131 case 1:
132 case 3:
133 case 5:
134 case 7:
135 case 8:
136 case 10:
137 case 12: if(dRTC>=32) {dRTC=1;mdRTC++;if(mdRTC==13) {mdRTC =1;yRTC=modulo(yRTC++,100);}} break;
138 case 4:
139 case 6:
140 case 9:
141 case 11: if(dRTC>=31) {dRTC=1;mdRTC++;} break;
142 case 2: if (dRTC >= 30) {dRTC=1;mdRTC++;break;}
143 if (dRTC ==29) {if (!(yRTC & 0x03)) break;dRTC=1;mdRTC++;}
144 }
145  
146 }
147  
148  
149  
150 #int_TIMER1 // RTC
151 TIMER1_isr()
152 {
153 sRTC=sRTC+16;
154 if (sRTC >= 60)
155 {
156 mRTC++;sRTC=modulo(sRTC,60); //1min
157 if (mRTC>=60) {hRTC++;mRTC=0;} //1hod
158 if ((mRTC & TEST_V_BATT) == TEST_V_BATT) test_batt=true;
159 if (hRTC>=24) {hRTC=0;set_date();} //1den
160 }
161 refresh=true;
162 if (tik_to_sleep) tik_to_sleep--;
163 }
164  
165 void ee_head() //ulozeni hlavicky do ee cas,datum,zpusob logovani
166 { //v ee 100hhhhh /hodiny/,l0mmmmmm /log + minuty/,000ddddd /den/,yyyymmmm /rok-7,mesic/
167 int8 data;
168 log=true;
169 if (!log_switch) return;
170 if (ee_offset>5) {
171 data=read_eeprom(ee_offset-4);
172 if (bit_test(data,7)) ee_offset=ee_offset-4;
173 }
174 if (ee_offset>=(MAX_EEPROM-5)) {log=false;return;}
175 log_interval=0;
176 data=hRTC;
177 bit_set(data,7);
178 write_eeprom(ee_offset++,data);
179 data=mRTC;
180 if (bit_test(log_switch,0)) bit_set(data,7);
181 write_eeprom(ee_offset++,data);
182 write_eeprom(ee_offset++,dRTC);
183 data=((yRTC-7) << 4)|mdRTC;
184 write_eeprom(ee_offset++,data);
185 }
186  
187  
188  
189 void menu_proces(int8 key) //menu zobrazene na LCD pri citani
190 {
191 switch (key)
192 {
193 case TL1: menu_A=2;refresh=true;clear_lcd();return;
194 case TL2: if (log) log=false;
195 else ee_head();
196 break;
197 case TL3: menu_B=modulo(++menu_B,6);break;
198 }
199 printf(lcd_putc,"\rdif=%lu ",dif);
200 lcd_gotoxy(11,1);
201 if (log) printf(lcd_putc,"L"); //pokud se loguje, zobraz L
202 else printf(lcd_putc," ");
203 if (bkg) printf(lcd_putc,"B"); //pokud jiz je BKG,zobraz B
204 lcd_gotoxy(14,1);
205 printf(lcd_putc,"%3u\n",(int8)(MAX_EEPROM-ee_offset)/2); //zbivajici misto v ee
206  
207 switch (menu_B)
208 {
209 case 0: printf(lcd_putc,"n=%lu",gmcount);break;
210 case 1: printf(lcd_putc,"min=%Lu",min);break;
211 case 2: printf(lcd_putc,"max=%lu",max);break;
212 case 3: printf(lcd_putc,"avg=%lu",avg);break;
213 case 4: printf(lcd_putc,"bkg=%lu",bkg);break;
214 case 5: printf(lcd_putc,"ontime=%lu:%02d ",mincount,sTIK);break;
215 }
216 }
217  
218 void send_data() //posle data z ee na rs232 9600 8N1
219 {
220 int8 i;
221 int16 data;
222 int8 *adr;
223 for (i=2;i<ee_offset;i)
224 {
225 adr=&data;
226 *adr=read_eeprom(i++);
227 if (bit_test(*adr,7)) //test, zda se nejedna o hlavicku v ee
228 {
229 bit_clear(*adr,7);
230 printf("\r\n%d:",*adr);
231 *adr=read_eeprom(i++);
232 printf("%02d ",(0x3f&*adr));
233 adr++;*adr=read_eeprom(i++);
234 printf("%d/",*adr);
235 *adr=read_eeprom(i++);
236 printf("%02d/",*adr&0x0f);
237 *adr=(*adr>>4)+7;
238 printf("%02d ",*adr);
239 adr--;
240 if (bit_test(*adr,7)) printf("1min");
241 else {*adr=LOG_PERIOD;printf("%umin",*adr);}
242  
243 }
244 else{
245 data=data<<8;
246 *adr=read_eeprom(i++);
247 printf("\r\n%lu",data);
248 }
249  
250 }
251 }
252  
253 void display(int8 key) //zobrazeni na LCD - zakladni menu
254 {
255 int8 mon,year; //pomocne promenne
256 if (key) clear_lcd();
257 keyp=0;
258 refresh=false;
259 if (menu_A>1) { //zmena pri stisku tl spolecna pro vetsinu menu_A
260  
261 if (key==TL3) {menu_A++;if (menu_A>11) menu_A=2;} //TL3 pak rolluj v menu_A
262 if ( ( menu_A != 10 ) && ( menu_A != 6 ) && (menu_A != 11) )
263 {
264 if (key==TL1)
265 {
266 if (counters) menu_A=1;
267 else menu_A=0;
268 key=0;
269 }
270 else printf(lcd_putc,"\r\nesc cr roll\r");
271 }
272 }
273  
274 switch (menu_A) //hlavni menu
275 {
276 case 0: min=0xffff; //zakladni menu po resetu, nastaveni promennych
277 max=gmcount=gmcount_sm=gmcount_p=timer_s=timer_n=mincount=dif=avg=bkg=0;
278 vypocet=sleep=counters=log=echo_switch=false;
279 test_batt = true;
280 log_switch=read_eeprom(EE_LOG_SWITCH);
281 ee_offset=read_eeprom(EE_LOG_OFFSET);
282 output_high(HV_ENABLE);
283 printf(lcd_putc,"\r%d:%02d %d.%d.%02d \nmenu off start",hRTC,mRTC,dRTC,mdRTC,yRTC);
284 switch (key)
285 {
286 case TL1: menu_A=2;break;
287 case TL2: menu_A=menu_B=0;sleep=true;break;
288 case TL3: menu_A=1;menu_B=0;
289 output_low(HV_ENABLE);
290 printf(lcd_putc,"\fSTART HV 400V");
291 delay_ms(2000);
292 counters=true;
293 break;
294 }
295 if (key) {refresh=true;clear_lcd();}
296 break;
297 case 1: menu_proces(key);break; //skok na menu zobrazujici vypoctene a nacitane promenne
298 case 3: if (key==TL2) {log_switch=modulo(++log_switch,3);write_eeprom(EE_LOG_SWITCH,log_switch);log=false;}
299 switch (log_switch)
300 {
301 case 0: printf(lcd_putc,"log \176 rs232");break;
302 case 1: printf(lcd_putc,"log \176 eeprom 1m");break;
303 case 2: mon=LOG_PERIOD;printf(lcd_putc,"log \176 eeprom %um",mon);break;
304 //case 3: printf(lcd_putc,"log \176 off ");break;
305 }
306 break;
307 case 9: printf(lcd_putc,"OFF (stand by)");
308 if (key==TL2) {menu_A=menu_B=0;sleep=true;output_high(HV_ENABLE);}
309 break;
310 case 8: if (key==TL2) if (echo_switch) echo_switch=0;else echo_switch=1;
311  
312 if (echo_switch) printf(lcd_putc,"echo on");
313 else printf(lcd_putc,"echo off");
314 break;
315 case 4: if (key==TL2) send_data();
316 printf(lcd_putc,"send log \176 rs232");
317 break;
318 case 5: if (key==TL2) {log=false;ee_offset=2;write_eeprom(EE_LOG_OFFSET,2);}
319 printf(lcd_putc,"erase eeprom %3u",(int8)(MAX_EEPROM-ee_offset)/2);
320 break;
321 case 2: printf(lcd_putc,"STOP & clear");
322 if (key==TL2) {menu_A=0;menu_B=0;refresh=true;}
323 break;
324 case 7: printf(lcd_putc,"batterie ");
325 //if (!input(CHARGE)) {printf(lcd_putc,"charge");break;}
326 if ( key == TL2 || counters )
327 {
328 if ( !counters ) {output_low(HV_ENABLE);delay_ms(30);}
329 analog = (float) (read_adc());
330 analog = 1024/analog*1.5 + 0.18;
331 if ( !counters ) output_float(HV_ENABLE);
332 printf(lcd_putc,"%1.2fV",analog);
333 }
334 break;
335 case 6: if (key == TL2) {pwm++;if (pwm > 10) pwm --;}
336 if (key == TL1) {pwm--;if (pwm < 2) pwm ++;}
337 set_pwm1_duty(pwm);
338 printf(lcd_putc,"contrast: %d\n - + roll",pwm);
339 break;
340 case 10: if (key==TL2) {set_timer1(0);sRTC=0;mRTC=modulo(++mRTC,60);}
341 if (key==TL1) hRTC=modulo(++hRTC,24);
342 printf(lcd_putc,"\rtime %2d:%02d\nhod min roll",hRTC,mRTC);
343 break;
344 case 11: if (key==TL1) {mon=mdRTC;year=yRTC;set_date();mdRTC=mon;year=yRTC;}
345 if (key==TL2) {mon=dRTC;year=yRTC;dRTC=32;set_date();year=yRTC;}
346 if (key==0x30) {mon=mdRTC;yRTC++;dRTC--;set_date();}
347 printf(lcd_putc,"\rdate %2d.%02d.%02d\nday mon roll",dRTC,mdRTC,yRTC);
348 break;
349 }
350 }
351  
352 void counters_fce()
353 {
354 int8 *adr;
355 if (vypocet) //1x za minutu se provede vypocet a log
356 {
357 dif=gmcount_sm-gmcount_p;
358 gmcount_p=gmcount_sm;
359 avg=gmcount_sm/mincount;
360 if (dif>max) max=dif;
361 if (dif<min) min=dif;
362 if (mincount==5) bkg=gmcount_sm/5;
363 vypocet=false;
364 refresh=true;
365  
366 if (log)
367 {
368 //if (log_switch && (ee_offset>(MAX_EEPROM-2))) {log=false;return;}
369 switch (log_switch)
370 {
371 case 0: printf("\n\r%d:%02d %2d/%02d/%02d dif=%lu",hRTC,mRTC,dRTC,mdRTC,yRTC,dif);break;
372 case 2: if (log_interval) break;
373 case 1: adr=&dif;adr++;bit_clear(*adr,7);
374 write_eeprom(ee_offset++,*adr);
375 write_eeprom(ee_offset++,*(--adr));
376 write_eeprom(EE_LOG_OFFSET,ee_offset);
377 if (ee_offset > (MAX_EEPROM-2)) log=false;
378 break;
379 }
380 log_interval=modulo(++log_interval,LOG_PERIOD);
381 }
382 }
383 }
384  
385 void echo_fce()
386 {
387 int8 a,c;
388 int16 b;
389 if (!echo_tik || !counters) return;
390 //if (echo_switch==2) {echo_switch=1;echo_cycle=ECHO_MAX_CYCLE/echo_tik;echo_timer=0;}
391 if (echo_tik == 1)
392 {
393 for (a=0;a<2;a++) {output_high(ECHO_PIN1);delay_us(160);output_low(ECHO_PIN1);delay_us(160);}
394 echo_tik=0;
395 }
396 else /*if ((echo_timer == echo_cycle) || (!echo_timer))*/
397 {
398 echo_switch=1;
399 c=echo_tik;
400 if (echo_tik <40) {a=40/c;b=0;}
401 if ((echo_tik >=40) && (echo_tik < 60)) {a=0;b=40000/c;}
402 if (echo_tik >=60) {a=0;b=160;}
403 while (echo_tik && (echo_switch==1) && !kbd_press())
404 {
405 echo_timer=0;
406 output_high(ECHO_PIN1);
407 delay_us(160);
408 output_low(ECHO_PIN1);
409 piezo=~piezo;
410 delay_us(b);
411 delay_ms(a);
412 }
413  
414 //output_bit(ECHO_PIN2,piezo);
415 }
416 echo_timer++;
417 }
418  
419 void pin_set_sleep()
420 {
421 #use fast_IO(A)
422 set_tris_A(0x15);
423 output_A(0x2a);
424 #use standard_IO(A)
425 #use fast_IO(B)
426 set_tris_B(0x70);
427 output_B(0x8f);
428 #use standard_IO(B)
429 #use fast_IO(C)
430 set_tris_C(0x2);
431 output_C(0x84);
432 #use standard_IO(C)
433 }
434  
435 void sleep_fce()
436 {
437 /*if (!input(CHARGE)) // pokud se nabiji, pak nespi
438 {
439 printf(lcd_putc,"\fcharged batt");
440 tik_to_sleep = 0;
441 while (!tik_to_sleep) if (input(CHARGE)) return;
442 kbd_getc();
443 sleep = false;
444 }
445 else */
446 {
447  
448 //setup_timer_0(RTCC_DIV_1|RTCC_INTERNAL);
449 //setup_timer_1(T1_DISABLED);
450 //setup_timer_2(T2_DIV_BY_16,249,10);
451  
452  
453 counters=false;
454 printf(lcd_putc,"\fchrrr");
455 delay_ms(1000);
456 setup_adc_ports(ADC_OFF);
457 setup_ccp1(CCP_OFF);
458 //SET_TRIS_A(0xFF);
459 //SET_TRIS_B(0xFF);
460 //SET_TRIS_C(0xFF);
461 pin_set_sleep();
462 do {sleep();delay_cycles(1);} while ( kbd_state!=0x20 /*&& input(CHARGE)*/ );
463 #use fast_IO(B)
464 set_tris_B(0x70);
465 output_B(0);
466 #use standard_IO(B)
467 setup_adc_ports(AN0);
468 setup_adc(ADC_CLOCK_DIV_16);
469 set_adc_channel(0);
470 //setup_timer_0(RTCC_DIV_1|RTCC_EXT_L_TO_H);
471  
472 //setup_timer_2(T2_DIV_BY_16,249,10);
473 //setup_ccp1(CCP_PWM);
474  
475 menu_A=menu_B=0;
476 setup_ccp1(CCP_PWM);
477 set_PWM1_duty(pwm);
478 delay_ms(200);
479 output_low(LCD_ENABLE);
480 output_high(HV_ENABLE);
481 lcd_init();
482 //printf(lcd_putc,"\fhello");
483 delay_ms(1000);kbd_getc();
484 keyp=0;
485 sleep=false;
486 refresh=true;
487 }
488 }
489  
490  
491 void main()
492 {
493 setup_adc_ports(AN0);
494 setup_adc(ADC_CLOCK_DIV_16);
495 set_adc_channel(0);
496 setup_timer_0(RTCC_DIV_1|RTCC_EXT_L_TO_H);
497 setup_timer_1(T1_EXTERNAL|T1_DIV_BY_8|T1_CLK_OUT);
498 setup_timer_2(T2_DIV_BY_16,249,10);
499 setup_ccp1(CCP_PWM);
500 set_PWM1_duty(0x5);
501  
502 enable_interrupts(INT_TIMER2);
503 enable_interrupts(INT_RB);
504 enable_interrupts(INT_TIMER1);
505 enable_interrupts(GLOBAL);
506  
507 output_low(LCD_ENABLE);
508 KBD_init();
509 LCD_init();
510 pwm=5;
511 sRTC=0;
512 mRTC=0;
513 hRTC=0;
514 dRTC=18;
515 mdRTC=10;
516 yRTC=07;
517  
518 menu_A=menu_B=0;
519 refresh=true;
520 keyp=0;
521  
522  
523 while (TRUE)
524 {
525 if (refresh) display(keyp); //povoleni zobrazeni(menu + fce tlacitek)
526 if (counters) { tik_to_sleep = TIME_TO_SLEEP;counters_fce();} //povoleni citacu,vypoctu a logovani
527 else if (! tik_to_sleep) sleep = true; //necita a zadny stisk tlacitek do TIME_TO_SLEEP pak sleep
528 if (echo_switch) echo_fce();
529 if (kbd_press()) //test stisku tlacitek,repeat, delay
530 {
531 if (!save_key) {save_key=kbd_getc();keyp=save_key;refresh=true;key_timer=KEYDELAY;} //delay key
532 if (!key_timer) {refresh=true;keyp=save_key;key_timer=KEYREPEAT;} //repeat key
533 }
534 else key_timer=save_key=keyp=0;
535 //echo (piezo)
536 if (test_batt && counters) //test napeti baterie
537 {
538 if (read_adc() > BATT_ENABLE)
539 {
540 printf(lcd_putc,"\flow batt");
541 delay_ms(2000);
542 sleep = true;
543 }
544 test_batt=false;
545 }
546 if (sleep) sleep_fce(); //sleep
547 //if (!timertest) {timertest=30;output_bit(PIN_C3,test);test=~test;}
548 //timertest--;
549 }
550  
551 }