Sei sulla pagina 1di 31

1 //Firmware per Progetto Funivia

2
3 //Autore: Biohazard
4 //MCU: PIC18F4525
5 //Data: Marzo 2015
6 //Versione: 1.2
7
8 #include <pic18.h>
9 #define _XTAL_FREQ 16000000 //Frequenza Oscillatore 16MHz
10 //necessario per delays in "pic18.h"
11
12 #pragma config OSC=HS //oscillatore esterno ad alta frequenza
13 #pragma config PWRT=ON //power up timer abilitato
14 #pragma config BOREN=OFF //brown out disabilitato
15 #pragma config WDT=OFF //watch dog timer disattivato
16 #pragma config LVP=OFF //programmazione a bassa tensione disabilitata
17 #pragma config PBADEN=OFF //pin ANx su PORTB settati come I/O digitali al reset
18 #pragma config CCP2MX=PORTC //ccp2 su portC
19
20 #include "ADCfunctions.h"
21 #include "LCDfunc16_4.h"
22 #include "PWMfunctions.h"
23 #include "ULTRASONICfunctions.h"
24 #include "settings.h"
25
26 #define versA '1' //versione sistema operativo, unità e
27 #define versB '2' //decimali
28 #define gradi 0 //posizione in RAM del display del carattere personalizzato
29 #define tmax_board 32 //temperatura massima consentita per le schede
30 #define tmax_motor 32 //temperatura massima consentita per il motore
31
32 #define led_g LATDbits.LATD7 //led consenso - verde
33 #define led_r LATDbits.LATD6 //led emergenza - rosso
34 #define buzzer LATDbits.LATD4 //cicalino
35 #define consenso PORTDbits.RD5 //pulsante consenso
36 #define power_gate_ir LATEbits.LATE0 //reset NE555 barriera ir - 1_on/0_off
37 #define gateIR_a PORTEbits.RE1 //gate ir A
38 #define gateIR_b PORTEbits.RE2 //gate ir B
39 #define sw_service PORTBbits.RB1 //pulsante servizio (gestito ad interrupt)
40 #define relay_fan_motor LATDbits.LATD2 //relè cambio velocità ventola motore
41 #define relay_fan_board LATCbits.LATC4 //relè cambio velocità ventola scheda
42 #define sw_fan_motor LATDbits.LATD3 //on/off ventola motore
43 #define sw_fan_board LATCbits.LATC5 //on/off ventola scheda
44 #define notte PORTBbits.RB2 //status illuminazione esterna
45
46 void interrupt tasks(void); //routine gestione interrupt ad alta priorità
47 void interrupt low_priority tasks_2(void); //interrupt bassa priorità
48 void crepuscolo(void); //funzione gestione notturna sistema
49 void arresto(void); //funzione gestione arresto di emergenza
50 void overflow(void); //funzione gestione compiti simultanei(multitasking)
51 void temp(void); //funzione stampa temperatura su LCD(da overflow();)
52
53 bit flagT; //flag per stampa valori temperatura su lcd
54 unsigned int boardTemp=0,motorTemp=0; //di appoggio
55 unsigned int temp_b=0,temp_m=0; // per sensori temperatura
56 unsigned int tboard=0,tmotor=0; //appoggio, valore temperatura
57 unsigned int i,k,j,m,n,q; //per cicli for vari
58 unsigned char p,rollover=0; //per ciclo for e conteggio overflow timer0
59 unsigned int time=0; //attesa per movimento cabine
60 unsigned int dist1,dist2; //di appoggio per distanza sensori ultrasuono
61 unsigned int duty1=0,duty2=0; //di appoggio per velocità motore
62
63 void main()
64 {
65 settings(); //settaggio registri TRISx
66
67 LCD_INIT(); //inizializzazione lcd
68 for(i=0;i<10;i++) __delay_ms(10); //ritardo di inizializzazione lcd
69 LCD_CUSTOMCHAR(gradi,6,9,9,6,0,0,0,0); //generazione carattere per "gradi"
70 LCD_CLEAR();
71
72 led_r=0; //spengo led emergenza
73 power_gate_ir=0; //led ir OFF
74
75 ADCsetup(); //settaggio registri adc
76 PWMsetup(89); //settaggio modulo CCP. PR2 impostato a 159. Frequenza=2.7KHz
77 ULTRAset(); //settaggio timer1 per sensori ad altrasuoni
78
79 INTCON2bits.NOT_RBPU=1; //pull-up disabilitati su portaB
80
81 T0CON=0b00000101; //settaggio registro timer0
82 /*
83 * bit 7 ----> Timer0 Off
84 * bit 6 ----> Timer0 is configured as an 16-bit timer/counter
85 * bit 5 ----> Timer0 Clock Source - Internal instruction cycle clock
86 * bit 4 ----> Timer0 Source Rising Edge
87 * bit 3 ----> Timer0 prescaler is assigned.
88 * Timer0 clock input comes from prescaler output.
89 * bit2-bit1-bit0 -> Timer0 Prescaler = 1:64
90 *
91 * Conteggio => 16uS
92 */
93
94 TMR0H=0x00;
95 TMR0L=0x00; //caricamento timer0
96 //overflow ogni 16uS*65536=1,048 Secondi
97
98 INTCON=0b11110000; //settaggio registro INTCON per interruzioni
99 /*
100 * bit 7 ----> Global Interrupt Enabled
101 * bit 6 ----> Peripheral Interrupt Enabled
102 * bit 5 ----> TMR0 Overflow Interrupt Enabled
103 * bit 4 ----> INT0 External Interrupt Enabled
104 * bit 3 ----> RB Port Change Interrupt Disabled
105 * bit 2 ----> TMR0 Overflow Interrupt Flag (cleared)
106 * bit 1 ----> INT0 External Interrupt Flag (cleared)
107 * bit 0 ----> RB Port Change Interrupt Flag (cleared)
108 */
109 TMR0IP=0; INTEDG0=0;
110 //INT0 sempre ad alta priorità di interruzione per default
111 INT1IE=1; INTEDG1=0; INT1IP=0; INT1IF=0;
112 INT2IE=0; //INT2 disabilitato
113 IPEN=1; //Priority levels on interrupts Enabled
114
115 LCD_GOTO(1,1);
116 LCD_PUTS("Benvenuti !!");
117 LCD_GOTO(2,1);
118 LCD_PUTS("Sistema di");
119 LCD_GOTO(3,1);
120 LCD_PUTS("trasporto");
121 LCD_GOTO(4,1);
122 LCD_PUTS("a fune");
123
124 for(i=0;i<50;i++) __delay_ms(10);
125 while(consenso==1); //aspetta consenso utente
126
127 LCD_CLR();
128 LCD_GOTO(1,1);
129 LCD_PUTS("INFO SISTEMA");
130 LCD_GOTO(2,1);
131 LCD_PUTS("Versione SO: ");
132 LCD_PUTCH(versA);
133 LCD_PUTCH('.');
134 LCD_PUTCH(versB);
135 LCD_GOTO(3,1);
136 LCD_PUTS("Realizzato da");
137 LCD_GOTO(4,1);
138 LCD_PUTS("Christian Sbrana");
139
140 for(i=0;i<50;i++) __delay_ms(10);
141 while(consenso==1); //aspetta consenso utente
142
143 /*****INTERROGAZIONE SISTEMI SICUREZZA*****/
144
145 LCD_CLR();
146 LCD_GOTO(1,1);
147 LCD_PUTS("Inizializzazione");
148 LCD_GOTO(2,1);
149 LCD_PUTS("impianto.");
150 LCD_GOTO(3,1);
151 LCD_PUTS("Analisi sistemi");
152 LCD_GOTO(4,1);
153 LCD_PUTS("di sicurezza");
154
155 for(i=0;i<50;i++) __delay_ms(10);
156 while(consenso==1); //aspetta consenso utente
157
158 time=20; //per attesa di 200mS
159 while(time) //finchè time non è zero
160 {
161 __delay_ms(10); //aspetto
162 time--; //decremento variabile
163 for(p=0;p<5;p++);
164 {
165 overflow(); //invoco funzione rilevazione temperatura
166 __delay_ms(40);
167 }
168 }
169 boardTemp=(boardTemp*5)/10; //conversione in gradi centigradi
170 if(boardTemp>tmax_board) //se temperatura zona scheda è troppo alta,
171 { //attiva sicurezza
172 led_g=0; //spegni led consenso
173 buzzer=1; //attiva sirena
174 led_r=1; //accendi led emergenza
175
176 LCD_CLR();
177 LCD_GOTO(1,1);
178 LCD_PUTS("! ATTENZIONE !");
179 LCD_GOTO(2,1);
180 LCD_PUTS("Temper. schede");
181 LCD_GOTO(3,1);
182 LCD_PUTS("elevata");
183 LCD_GOTO(4,1);
184 LCD_PUTS("Attesa consenso");
185
186 relay_fan_board=1; //velocità ventola scheda alta
187 sw_fan_board=1; //accendo ventola scheda
188
189 for(i=0;i<100;i++) __delay_ms(10); //aspetta un secondo
190 buzzer=0; //spegni buzzer
191
192 while(consenso==1); //aspetta consenso utente
193 __delay_us(50); //antirimbalzo pulsante
194
195 sw_fan_board=0; //spengo ventola scheda
196 led_r=0; //spegni led emergenza
197 led_g=1; //accendi led consenso
198 }
199
200 LCD_CLR();
201 LCD_GOTO(1,1);
202 LCD_PUTS("Controllo temp");
203 LCD_GOTO(2,1);
204 LCD_PUTS("schede: OK");
205
206 time=20; //per attesa di 200mS
207 while(time) //finchè time non è zero
208 {
209 __delay_ms(10); //aspetto
210 time--; //decremento variabile
211 for(p=0;p<5;p++);
212 {
213 overflow(); //invoco funzione rilevazione temperatura
214 __delay_ms(40);
215 }
216 }
217 motorTemp=(motorTemp*5)/10; //conversione in gradi centigradi
218 if(motorTemp>tmax_motor) //se temperatura zona motore è troppo alta,
219 { //attiva sicurezza
220 led_g=0; //spegni led consenso
221 buzzer=1; //attiva sirena
222 led_r=1; //accendi led emergenza
223
224 LCD_CLR();
225 LCD_GOTO(1,1);
226 LCD_PUTS("! ATTENZIONE !");
227 LCD_GOTO(2,1);
228 LCD_PUTS("Temper. motore");
229 LCD_GOTO(3,1);
230 LCD_PUTS("elevata");
231 LCD_GOTO(4,1);
232 LCD_PUTS("Attesa consenso");
233
234 relay_fan_motor=1; //velocità ventola motore alta
235 sw_fan_motor=1; //accendo ventola motore
236
237 for(i=0;i<100;i++) __delay_ms(10); //aspetta un secondo
238 buzzer=0; //spegni buzzer
239
240 while(consenso==1); //aspetta consenso utente
241 __delay_us(50); //antirimbalzo pulsante
242
243 sw_fan_motor=0; //spengo ventola motore
244 buzzer=0; //spegni sirena
245 led_r=0; //spegni led emergenza
246 led_g=1; //accendi led consenso
247 }
248
249 LCD_CLR();
250 LCD_GOTO(1,1);
251 LCD_PUTS("Controllo temp");
252 LCD_GOTO(2,1);
253 LCD_PUTS("schede: OK");
254 LCD_GOTO(3,1);
255 LCD_PUTS("Controllo temp");
256 LCD_GOTO(4,1);
257 LCD_PUTS("motore: OK");
258
259 led_g=1; //accendi led consenso
260
261 for(i=0;i<100;i++) __delay_ms(10); //attendi per 1 secondo
262
263 LCD_CLR();
264 LCD_GOTO(1,1);
265 LCD_PUTS("Controllo temp");
266 LCD_GOTO(2,1);
267 LCD_PUTS("schede: --.-");
268 LCD_GOTO(3,1);
269 LCD_PUTS("Controllo temp");
270 LCD_GOTO(4,1);
271 LCD_PUTS("motore: --.-");
272
273 for(i=0;i<50;i++) __delay_ms(10);
274 while(consenso==1) //aspetta consenso utente e aggiorna temperatura
275 {
276 for(p=0;p<5;p++);
277 {
278 overflow();
279 __delay_ms(40);
280 }
281 LCD_GOTO(2,9);
282 LCD_PUTUN((boardTemp*5)/10);
283 LCD_PUTCH('.');
284 LCD_PUTUN((boardTemp*5)%100);
285 LCD_PUTCH(' ');
286 LCD_PUTCH(gradi);
287 LCD_PUTS("C ");
288 LCD_GOTO(4,1);
289 LCD_PUTCH('m');
290 LCD_GOTO(4,9);
291 LCD_PUTUN((motorTemp*5)/10);
292 LCD_PUTCH('.');
293 LCD_PUTUN((motorTemp*5)%100);
294 LCD_PUTCH(' ');
295 LCD_PUTCH(gradi);
296 LCD_PUTS("C ");
297 }
298
299 power_gate_ir=1; //attiva emettitori ir barriera
300 __delay_us(100);
301 if((gateIR_a==1)||(gateIR_b==1)) //se almeno uno dei due gate è interrotto
302 {
303 led_g=0; //spegni led consenso
304 led_r=1; //accendi led emergenza
305
306 LCD_CLR();
307 LCD_GOTO(1,1);
308 LCD_PUTS("! ATTENZIONE !");
309 LCD_GOTO(2,1);
310 LCD_PUTS("Ostacolo in");
311 LCD_GOTO(3,1);
312 LCD_PUTS("stazione a monte");
313 LCD_GOTO(4,1);
314 LCD_PUTS("Attesa consenso");
315
316 for(i=0;i<50;i++) __delay_ms(10);
317 while(consenso==1) //aspetta consenso utente o
318 {
319 if((gateIR_a==0)&&(gateIR_b==0)) break; //se rimosso ostacolo, esci
320 //dal ciclo
321 }
322
323 __delay_us(50); //antirimbalzo pulsante
324
325 led_r=0; //spegni led emergenza
326 led_g=1; //accendi led consenso
327 }
328 power_gate_ir=0; //spegni emettitori ir barriera
329
330 LCD_CLR();
331 LCD_GOTO(1,1);
332 LCD_PUTS("Controllo");
333 LCD_GOTO(2,1);
334 LCD_PUTS("barriere");
335 LCD_GOTO(3,1);
336 LCD_PUTS("infrarossi");
337 LCD_GOTO(4,1);
338 LCD_PUTS("OK");
339
340 for(i=0;i<50;i++) __delay_ms(10);
341 while(consenso==1); //aspetta consenso utente
342 for(i=0;i<50;i++) __delay_ms(10);
343
344 /*****PRE-SEQUENZA*****/
345
346 //verifica barriera IR
347 power_gate_ir=1; //accendi gate ir
348 __delay_us(100);
349 if((gateIR_a==0)&&(gateIR_b==0)) //se entrambi i gate non sono interrotti
350 {
351 PWMdutyx(0,400); //gira motore in senso orario a velocità moderata
352
353 while(1) //azione diversa a seconda del gate interrotto
354 {
355 if(gateIR_a==1)
356 {
357 PWMdutyx(0,0); //spengo motore
358 break; //esci dal ciclo
359 }
360 if(gateIR_b==1)
361 {
362 PWMdutyx(0,0); //spengo motore
363
364 led_g=0; //spegni led consenso
365 led_r=1; //accendi led emergenza
366
367 LCD_CLR();
368 LCD_GOTO(1,1);
369 LCD_PUTS("! ATTENZIONE !");
370 LCD_GOTO(2,1);
371 LCD_PUTS("Postazione B");
372 LCD_GOTO(3,1);
373 LCD_PUTS("occupata-ERRORE");
374 LCD_GOTO(4,1);
375 LCD_PUTS("Attesa consenso");
376
377 for(i=0;i<50;i++) __delay_ms(10);
378 while(consenso==1); //aspetta consenso utente
379
380 led_r=0; //spegni led emergenza
381 break; //esci dal ciclo
382 }
383 if(consenso==0) //se premuto consenso vai avanti
384 {
385 PWMdutyx(0,0); //spengo motore
386 break; //esci dal ciclo
387 }
388 }
389 }
390 else if((gateIR_a==1)&&(gateIR_b==1)) //altrimenti se entrambi sono interrotti
391 {
392 led_g=0; //spegni led consenso
393 led_r=1; //accendi led emergenza
394
395 LCD_CLR();
396 LCD_GOTO(1,1);
397 LCD_PUTS("! ATTENZIONE !");
398 LCD_GOTO(2,1);
399 LCD_PUTS("Posizione");
400 LCD_GOTO(3,1);
401 LCD_PUTS("cabine errata");
402 LCD_GOTO(4,1);
403 LCD_PUTS("Attesa consenso");
404
405 for(i=0;i<50;i++) __delay_ms(10);
406 while(consenso==1) //aspetta consenso utente o
407 {
408 if((gateIR_a==0)&&(gateIR_b==0)) break; //se rimosso ostacolo, esci
409 //dal ciclo
410 }
411
412 led_r=0; //spegni led emergenza
413 led_g=1; //accendi led consenso
414 }
415 else //altrimenti se soltanto un gate è interrotto,
416 { //verifico di quale gate si tratta e agisco di conseguenza
417 if(gateIR_a==1) //se interrotto gate a
418 {
419 LCD_CLR();
420 LCD_GOTO(1,1);
421 LCD_PUTS("Posizione");
422 LCD_GOTO(2,1);
423 LCD_PUTS("cabine corretta");
424 LCD_GOTO(3,1);
425 LCD_PUTS("Attesa consenso");
426 LCD_GOTO(4,1);
427 LCD_PUTS("utente...");
428
429 for(i=0;i<50;i++) __delay_ms(10);
430 while(consenso==1); //aspetta consenso utente
431 }
432 if(gateIR_b==1) //se interrotto gate b
433 {
434 PWMdutyx(0,400); //gira motore in senso orario a velocità moderata
435
436 while(gateIR_a==0); //finchè gate a non è interrotto, aspetta
437
438 PWMdutyx(0,0); //spengo motore
439 }
440 }
441 power_gate_ir=0; //spegni gate ir
442
443 LCD_CLR();
444 LCD_GOTO(1,1);
445 LCD_PUTS("Controlli");
446 LCD_GOTO(2,1);
447 LCD_PUTS("avvenuti");
448 LCD_GOTO(3,1);
449 LCD_PUTS("Attesa consenso");
450 LCD_GOTO(4,1);
451 LCD_PUTS("avvio impianto");
452
453 for(i=0;i<50;i++) __delay_ms(10);
454 while(consenso==1); //aspetta consenso utente
455
456 LCD_CLR();
457 LCD_GOTO(1,1);
458 LCD_PUTS("Avvio impianto");
459 LCD_GOTO(2,1);
460 LCD_PUTS("in corso.");
461
462 led_r=0; //spegni led emergenza
463 for(j=0;j<3;j++) //triplo lampeggio led verde ogni 500ms
464 {
465 led_g=0;
466 for(i=0;i<50;i++) __delay_ms(10);
467 led_g=1;
468 for(i=0;i<50;i++) __delay_ms(10);
469 LCD_PUTCH('.');
470 }
471 led_g=0;
472 relay_fan_motor=0; //velocità ventola motore bassa
473 relay_fan_board=0; //velocità ventola scheda bassa
474 sw_fan_motor=1; //accendo ventola motore (velocità minima)
475 sw_fan_board=1; //accendo ventola scheda (velocità minima)
476
477 LCD_CLR();
478 LCD_GOTO(1,1);
479 LCD_PUTS("Temperatura");
480 LCD_GOTO(2,1);
481 LCD_PUTS("schede: -");
482 LCD_GOTO(3,1);
483 LCD_PUTS("Temperatura");
484 LCD_GOTO(4,1);
485 LCD_PUTS("motore: -");
486
487 for(p=0;p<5;p++);
488 {
489 overflow(); //invoco funzione rilevazione temperatura
490 __delay_ms(40);
491 }
492 LCD_GOTO(2,9);
493 LCD_PUTUN((boardTemp*5)/10);
494 LCD_PUTCH('.');
495 LCD_PUTUN((boardTemp*5)%100);
496 LCD_PUTCH(' ');
497 LCD_PUTCH(gradi);
498 LCD_PUTS("C ");
499 LCD_GOTO(4,9);
500 LCD_PUTUN((motorTemp*5)/10);
501 LCD_PUTCH('.');
502 LCD_PUTUN((motorTemp*5)%100);
503 LCD_PUTCH(' ');
504 LCD_PUTCH(gradi);
505 LCD_PUTS("C ");
506
507 TMR0ON=1; //abilitazione timer0 e avvio sistema multitasking
508 duty1=0; duty2=0; //azzero duty per il motore
509
510 /**** SEQUENZA PRINCIPALE ****/
511
512 while(1)
513 {
514 for(i=0;i<500;i++) //aspetta 5 secondi per carico passeggeri in cabina
515 {
516 __delay_ms(10);
517 if(notte==1) crepuscolo();//se crepuscolare si attiva, invoca funzione
518 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
519 }
520
521 //incremento velocità graduale cabina 1
522 duty1=300;
523 for(j=0;j<5;j++) //aumenta velocità per 5 volte
524 {
525 PWMdutyx(duty1,0);
526 duty1=duty1+5; //incrementa velocità dello 0.49% (ovvero duty di 5)
527 for(i=0;i<10;i++) __delay_ms(10); //aspetta 100mS
528 }
529 PWMdutyx(duty1,0);
530 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
531
532 dist1=ULTRAdist1(); //misura distanza
533 while(dist1<20) //finchè la cabina 1 è entro 20cm dalla stazione
534 {
535 dist1=ULTRAdist1(); //continua a misurare ed aspetta
536 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
537 }
538
539 //quando la cabina 1 supera la distanza dalla stazione, piena velocità
540 //in graduale aumento, riprendendo dal livello precedente
541 for(j=0;j<3;j++)
542 {
543 PWMdutyx(duty1,0);
544 duty1=duty1+60; //incrementa velocità dello 5.87% (ovvero duty di 60)
545 for(i=0;i<10;i++) __delay_ms(10); //aspetta 100mS
546 }
547 PWMdutyx(duty1,0);
548 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
549
550 time=1200; //per 12 secondi
551 while(time) //finchè time non è zero
552 {
553 __delay_ms(10); //aspetto
554 time--; //decremento variabile
555 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
556 }
557
558 dist2=ULTRAdist2(); //misura distanza
559 while(dist2>20) //finchè la cabina 2 è lontana dalla stazione
560 {
561 dist2=ULTRAdist2(); //continua a misurare ed aspetta
562 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
563 }
564
565 //quando arriva la cabina 2 in stazione, diminuisci velocità
566 while(duty1>300) //finchè la velocità non è sufficientemente bassa
567 {
568 duty1=duty1-20; //diminuisci velocità gradualmente
569 PWMdutyx(duty1,0);
570 for(i=0;i<10;i++) __delay_ms(10);//aspetta 100mS per graduale decrescita
571 }
572 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
573
574 //ferma motore quando le cabine sono in stazione
575 power_gate_ir=1; //accendo emettitori ir
576 __delay_ms(1);
577 while(gateIR_b==0); //finchè gate b non è interrotto da cabina 2, aspetta
578 PWMdutyx(0,0); //fermo motore
579 power_gate_ir=0; //spengo emettitori ir
580
581 duty1=0; duty2=0; //azzero duty per il motore
582 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
583
584 //*******ripeti per cabina opposta********//
585 for(i=0;i<500;i++) //aspetta 5 secondi per carico passeggeri in cabina
586 {
587 __delay_ms(10);
588 if(notte==1) crepuscolo();//se si attiva crepuscolare, incova funz
589 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
590 }
591
592 //incremento velocità graduale nel senso opposto al precedente cabina 2
593 duty2=300;
594 for(j=0;j<5;j++) //aumenta velocità per 5 volte
595 {
596 PWMdutyx(0,duty2);
597 duty2=duty2+5; //incrementa velocità dello 0.49% (ovvero duty di 5)
598 for(i=0;i<10;i++) __delay_ms(10); //aspetta 100mS
599 }
600 PWMdutyx(0,duty2);
601 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
602
603 dist2=ULTRAdist2(); //misura distanza
604 while(dist2<20) //finchè la cabina 2 è entro 20cm dalla stazione
605 {
606 dist2=ULTRAdist2(); //continua a misurare ed aspetta
607 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
608 }
609
610 //quando la cabina 2 supera la distanza dalla stazione, piena velocità
611 //in graduale aumento, riprendendo dal livello precedente
612 for(j=0;j<3;j++)
613 {
614 PWMdutyx(0,duty2);
615 duty2=duty2+60; //incrementa velocità dello 5.87% (ovvero duty di 60)
616 for(i=0;i<10;i++) __delay_ms(10); //aspetta 100mS
617 }
618 PWMdutyx(0,duty2);
619 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
620
621 time=1200; //per 12 secondi
622 while(time) //finchè time non è zero
623 {
624 __delay_ms(10); //aspetto
625 time--; //decremento variabile
626 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
627 }
628
629 dist1=ULTRAdist1(); //misura distanza
630 while(dist1>20) //finchè la cabina 1 è lontana dalla stazione
631 {
632 dist1=ULTRAdist1(); //continua a misurare ed aspetta
633 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
634 }
635
636 //quando arriva la cabina 1 in stazione, diminuisci velocità
637 while(duty2>300) //finchè la velocità non è sufficientemente bassa
638 {
639 duty2=duty2-20; //diminuisci velocità gradualmente
640 PWMdutyx(0,duty2);
641 for(i=0;i<10;i++) __delay_ms(10);//aspetta 100mS per graduale decrescita
642 }
643 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
644
645 //ferma motore quando le cabine sono in stazione
646 power_gate_ir=1; //accendo emettitori ir
647 __delay_ms(1);
648 while(gateIR_a==0); //finchè gate a non è interrotto da cabina 1, aspetta
649 PWMdutyx(0,0); //fermo motore
650 power_gate_ir=0; //spengo emettitori ir
651
652 duty1=0; duty2=0; //azzero duty per il motore
653 if(flagT==1) temp(); //se flag temp è a 1, invoca funzione stampa temp
654 }
655 }
656
657 void interrupt tasks(void) //interrupt alta priorità da int0
658 {
659 if(INT0IF==1) //se premuto pulsante "arresto"
660 {
661 arresto(); //invoco relativa funzione secondaria
662 INT0IF=0; //resetto flag di interruzione
663 }
664 }
665
666 void interrupt low_priority tasks_2(void) //interrupt da timer0, int1, int2
667 {
668 if(TMR0IF==1) //se accade l'overflow del timer0 (passato 1S)
669 {
670 overflow(); //invoco funzione
671 TMR0H=0x00;
672 TMR0L=0x00;
673 TMR0IF=0; //resetto flag di interruzione
674 }
675 if(INT1IF==1) //se premuto pulsante "service"
676 {
677 sw_fan_board=~sw_fan_board; //inverti stato ventola scheda
678 sw_fan_motor=~sw_fan_motor; //inverti stato ventola motore
679
680 for(q=0;q<100;q++) __delay_ms(10); //aspetta un secondo
681 if(sw_service==0) //se dopo attesa pulsante ancora premuto
682 {
683 relay_fan_board=~relay_fan_board; //inverti velocità ventola scheda
684 relay_fan_motor=~relay_fan_motor; //inverti velocità ventola motore
685 for(q=0;q<100;q++) __delay_ms(10); //aspetta mezzo secondo
686 }
687 INT1IF=0; //resetto flag di interruzione
688 }
689 }
690
691 void crepuscolo(void)
692 {
693 led_g=0; //spegni led consenso
694 buzzer=1; //attiva sirena
695 led_r=1; //accendi led emergenza
696
697 //disabilito momentaneamente le interruzioni da timer0
698 TMR0ON=0;
699 TMR0IF=0;
700 TMR0IE=0;
701
702 LCD_CLR();
703 LCD_GOTO(1,1);
704 LCD_PUTS("Illuminazione");
705 LCD_GOTO(2,1);
706 LCD_PUTS("esterna bassa.");
707 LCD_GOTO(3,1);
708 LCD_PUTS("Arresto fra");
709 LCD_GOTO(4,1);
710 LCD_PUTS("10 secondi...");
711
712 for(n=0;n<100;n++) __delay_ms(10); //aspetta 1 secondo
713
714 buzzer=0; //spegni sirena
715 led_r=0; //spegni led emergenza
716
717 for(n=0;n<1000;n++) //attesa di 10 secondi, con verifica consenso premuto
718 {
719 if(consenso==0) //se premuto
720 { //rendo di nuovo disponibili le interruzioni da timer0
721 TMR0ON=1;
722 TMR0H=0x00; TMR0L=0x00;
723 TMR0IF=0;
724 TMR0IE=1;
725
726 LCD_CLR(); //pulisco display
727 return; //torno al main
728 }
729 __delay_ms(10);
730 }
731
732 buzzer=1; //attiva sirena
733 led_r=1; //accendi led emergenza
734
735 for(n=0;n<100;n++) __delay_ms(10); //aspetta 1 secondo
736
737 buzzer=0; //spegni sirena
738 led_r=0; //spegni led emergenza
739 PWMdutyx(0,0); //spengo motore
740 sw_fan_board=0; //spengo ventola scheda e
741 sw_fan_motor=0; //ventola motore
742 GIE=0; //disabilito interruzioni
743
744 LCD_CLR();
745 LCD_GOTO(1,1);
746 LCD_PUTS("! ATTENZIONE !");
747 LCD_GOTO(2,1);
748 LCD_PUTS("Chiusura");
749 LCD_GOTO(3,1);
750 LCD_PUTS("Impianto.");
751 LCD_GOTO(4,1);
752 LCD_PUTS("Buonanotte");
753
754 while(1); //ciclo infinito di arresto del sistema
755 //oppure si risolve con una sleep
756 }
757
758 void arresto(void)
759 {
760 PWMdutyx(0,0); //spegni motore
761
762 led_g=0; //spegni led consenso
763 led_r=1; //accendi led emergenza
764 buzzer=1; //accendi sirena
765
766 LCD_CLR();
767 LCD_GOTO(1,1);
768 LCD_PUTS("! ATTENZIONE !");
769 LCD_GOTO(2,1);
770 LCD_PUTS("Stato Emergenza");
771 LCD_GOTO(3,1);
772 LCD_PUTS("attivato.");
773 LCD_GOTO(4,1);
774 LCD_PUTS("Attesa consenso");
775
776 for(m=0;m<100;m++) __delay_ms(10); //aspetto un secondo
777 buzzer=0; //spengo cicalino
778
779 while(consenso==1) //aspetta consenso utente
780 {
781 if(sw_service==0)
782 {
783 sw_fan_motor=1; //accendi ventole
784 sw_fan_board=1;
785 relay_fan_motor=~relay_fan_motor; //cambia stato ventole
786 relay_fan_board=~relay_fan_board;
787 for(m=0;m<50;m++) __delay_ms(10); //attesa antirimbalzo
788 }
789 } //quando consenso viene premuto, prosegue con il programma
790
791 LCD_CLR(); //pulisci display
792 relay_fan_motor=0; //diminuisci velocità ventola motore
793 relay_fan_board=0; //diminuisci velocità ventola scheda
794 led_r=0; //spegni led emergenza
795 led_g=1; //accendi led consenso
796 PWMdutyx(duty1,duty2);
797 }
798
799 void overflow(void)
800 {
801 rollover++; //incremento varibile ad ogni overflow
802
803 temp_b=ADCconv(1); //rilevazione temperatura scheda
804 tboard=tboard+temp_b; //sommo le rilevazioni
805 __delay_ms(10);
806 temp_m=ADCconv(0); //rilevazione temperatura motore
807 tmotor=tmotor+temp_m; //sommo le rilevazioni
808 __delay_ms(10);
809
810 if(rollover==5) //dopo 5 interruzioni da timer0 (rollover inizializzata a 0)
811 {
812 boardTemp=tboard/5; //faccio le medie
813 motorTemp=tmotor/5; //dei valori
814 flagT=1; //flag per segnalare stampa valori temperatura
815 tboard=0; tmotor=0; //resetto variabili temperatura
816 rollover=0; //azzero variabile conteggio overflow
817 }
818 }
819
820 void temp(void)
821 {
822 boardTemp=(boardTemp*5)/10; //conversione in gradi centigradi
823 if(boardTemp>tmax_board)//se temp zona scheda è troppo alta, attiva sicurezza
824 {
825 PWMdutyx(0,0); //fermo motore
826 led_g=0; //spegni led consenso
827 buzzer=1; //attiva sirena
828 led_r=1; //accendi led emergenza
829
830 LCD_CLR();
831 LCD_GOTO(1,1);
832 LCD_PUTS("! ATTENZIONE !");
833 LCD_GOTO(2,1);
834 LCD_PUTS("Temper. schede");
835 LCD_GOTO(3,1);
836 LCD_PUTS("elevata.");
837 LCD_GOTO(4,1);
838 LCD_PUTS("Attesa consenso");
839
840 sw_fan_board=1; //accendi ventola scheda
841 relay_fan_board=1; //aumenta velocità ventola scheda
842
843 for(k=0;k<100;k++) __delay_ms(10); //aspetta 1 secondo
844 buzzer=0; //spegni sirena
845
846 while(consenso==1); //aspetta consenso utente
847
848 led_r=0; //spegni led emergenza
849 led_g=1; //accendi led consenso
850 relay_fan_board=0; //diminuisci velocità ventola scheda
851 }
852
853 motorTemp=(motorTemp*5)/10; //conversione in gradi centigradi
854 if(motorTemp>tmax_motor)//se temp zona motore è troppo alta, attiva sicurezza
855 {
856 PWMdutyx(0,0); //fermo motore
857 led_g=0; //spegni led consenso
858 buzzer=1; //attiva sirena
859 led_r=1; //accendi led emergenza
860
861 LCD_CLR();
862 LCD_GOTO(1,1);
863 LCD_PUTS("! ATTENZIONE !");
864 LCD_GOTO(2,1);
865 LCD_PUTS("Temper. motore");
866 LCD_GOTO(3,1);
867 LCD_PUTS("elevata.");
868 LCD_GOTO(4,1);
869 LCD_PUTS("Attesa consenso");
870
871 sw_fan_motor=1; //accendi ventola motore
872 relay_fan_motor=1; //aumenta velocità ventola motore
873
874 for(k=0;k<100;k++) __delay_ms(10); //aspetta 1 secondo
875 buzzer=0; //spegni sirena
876
877 while(consenso==1); //aspetta consenso utente
878
879 led_r=0; //spegni led emergenza
880 led_g=1; //accendi led consenso
881 relay_fan_motor=0; //diminuisci velocità ventola motore
882 }
883
884 LCD_CLR();
885 LCD_GOTO(1,1);
886 LCD_PUTS("Temperatura");
887 LCD_GOTO(2,1);
888 LCD_PUTS("schede: ");
889 LCD_GOTO(2,9);
890 LCD_PUTUN(boardTemp); //scrivo temperatura scheda su display
891 LCD_PUTCH('.');
892 LCD_PUTUN((boardTemp*5)%100);
893 LCD_PUTCH(' ');
894 LCD_PUTCH(gradi);
895 LCD_PUTS("C ");
896 LCD_GOTO(3,1);
897 LCD_PUTS("Temperatura");
898 LCD_GOTO(4,1);
899 LCD_PUTS("motore: ");
900 LCD_GOTO(4,9);
901 LCD_PUTUN(motorTemp); //scrivo temperatura motore su display
902 LCD_PUTCH('.');
903 LCD_PUTUN((motorTemp*5)%100);
904 LCD_PUTCH(' ');
905 LCD_PUTCH(gradi);
906 LCD_PUTS("C ");
907
908 led_r=0; //spegni led emergenza
909 led_g=0; //spegni led consenso
910 flagT=0; //azzero flag
911 }
1 /* File: settings.h
2 * Author: Biohazard
3 * Created on 27 marzo 2015, 20.54
4 * Settaggio registri di direzione delle porte
5 */
6 void settings(void)
7 {
8 TRISA=0x2b;
9 /* TRISA=0b00101011;
10 *
11 * RA7-RA6 -----> oscillatore USCITE
12 * RA5 ---------> implementazione INGRESSO
13 * RA4 ---------> lcd USCITA
14 * RA3 ---------> implementazione INGRESSO
15 * RA2 ---------> sense resistor USCITA (non connesso)
16 * RA1 ---------> sonda temp motore INGRESSO
17 * RA0 ---------> temperatura scheda INGRESSO
18 */
19 TRISB=0x07;
20 /* TRISB=0b00000111;
21 *
22 * RB7-RB6-RB5 -> programmaz. - lcd USCITE
23 * RB4 ---------> lcd USCITA
24 * RB3 ---------> lcd USCITA
25 * RB2 ---------> interr. illumin. INGRESSO
26 * RB1-RB0 -----> pulsanti interrupt INGRESSI
27 */
28 TRISC=0xc1;
29 /* TRISC=0b11000001;
30 *
31 * RC7-RC6 -----> implementaz. usart INGRESSI
32 * RC5-RC4 -----> ventole USCITE
33 * RC3 ---------> trigger ultrasuono2 USCITA
34 * RC2-RC1 -----> ccp motore USCITE
35 * RC0 ---------> echo ultrasuono2 INGRESSO
36 */
37 TRISD=0x21;
38 /* TRISD=0b00100001;
39 *
40 * RD7-RD6 -----> led info USCITE
41 * RD5 ---------> pulsante consenso INGRESSO
42 * RD4 ---------> cicalino USCITA
43 * RD3-RD2 -----> ventole USCITE
44 * RD1 ---------> trigger ultrasuono1 USCITA
45 * RD0 ---------> echo ultrasuono1 INGRESSO
46 */
47 TRISE=0x06;
48 /* TRISE=0b00000110;
49 *
50 * RE0 ---------> reset gate ir USCITA
51 * RE1-RE2 -----> gate ir INGRESSI
52 */
53 }
1 /* File: ADCfunctions.h
2 * Author: Biohazard
3 * Created on Marzo 2015
4 *******************************************************************************
5 Analogic-Digital Converter ROUTINES FOR:
6 - ADCON registers Setup
7 - Conversion
8 *******************************************************************************
9 -- Based and tested on PIC18F4525
10 *******************************************************************************
11 ADC ROUTINES DESCRIPTION:
12
13 - ADCsetup() -------> Initializes ADC registers
14
15 - unsigned int ADCconv(unsigned char ch) -> Sets channel, starts conversion
16 and gives the result
17 *******************************************************************************/
18
19 void ADCsetup();
20 unsigned int ADCconv(unsigned char ch);
21
22 void ADCsetup()
23 {
24 ADCON1=0b00001101;
25 /*
26 * bit7-bit6 --> none
27 * bit5 --> Vref- = Vss
28 * bit4 --> Vref+ = Vdd
29 * bit3-bit2-bit1-bit0 --> only AN1,AN0 are setted as analog input
30 */
31
32 ADCON2=0b10001010;
33 /*
34 * bit7 --> right justified
35 * bit6 --> none
36 * bit5-bit4-bit3 --> A/D Acquisition Time = 2Tad
37 * bit2-bit1-bit0 --> A/D Conversion Clock = Fosc/32 (Tad=2uS)
38 */
39 }
40
41 unsigned int ADCconv(unsigned char ch)
42 {
43 unsigned int res=0;
44
45 ADCON0=ch<<2; //select channel for conversion
46
47 ADCON0bits.ADON=1; //enable converter module
48
49 __delay_us(20); //charge capacitor delay
50
51 ADCON0bits.GO=1; //start conversion
52
53 while(ADCON0bits.DONE==0); //wait the conversion end
54
55 res=(ADRESH<<8)+ADRESL; //result of conversion
56 //value between 0 and 1023 (10 bit)
57
58 return res; //the result goes to the caller function
59 }
1 /* File: LCDfunctions.h
2 * Author: Biohazard
3 * Aprile 2015
4 *******************************************************************************
5 -- For LCD Display 16x4 based on HD44780 controller
6 -- R/W pin select is not available. This software works only in write mode
7 -- LCD works in 4bit mode
8 *******************************************************************************
9 -- USER'S ROUTINES DESCRIPTION:
10
11 LCD_EN() -------------> Display Enable function
12
13 LCD_INIT() -----------> Initialize the LCD. Necessary for the first time
14 the display is used and later before LCD's routines
15
16 LCD_CLEAR() ----------> Clears display.
17
18 LCD_CLR() ------------> Clears Display
19
20 LCD_HOME() -----------> Home LCD. Cursor to start position. Address Counter begin at 0
21
22 LCD_WRITE('unsigned char') -> Write on LCD. Remember to select RS mode (pin)
23
24 LCD_CMD('char') ------> Sends a command to the LCD.
25
26 LCD_GOTO(line,pos) ---> Set the Cursor to a specified Line and position.
27
28 LCD_PUTCH('char') ----> Writes a character on LCD (ASCII code). You can use this
29 for characters and numbers
30
31 LCD_PUTS("string") ---> Writes a string on LCD. You can use this for words and
32 string of numbers
33
34 LCD_PUTUN(number) ---> Writes an Unsigned Number on LCD.
35 It works both with INT (16bit) and CHAR (8bit).
36
37 LCD_PUTSN(number) ---> Writes a Signed Number on LCD (with Sign if <0).
38 It works both with INT (16bit) and CHAR (8bit).
39
40 LCD_CUSTOMCHAR(pos,byte1,byte2,byte3,byte4,byte5,byte6,byte7,byte8) -->
41 customizes the character in the CGRAM at position (pos)
42 bytes from 1 to 8 are the pattern of the new character.
43 WARNING: this function can only used if the flag
44 LCD_CANCUSTOMIZE is set to 1
45 */
46 #include <htc.h>
47 // Pin Configuration
48 #define lcd_RS LATAbits.LATA4 //Register Select
49 #define lcd_EN LATBbits.LATB3 //Enable
50 #define lcd_D4 LATBbits.LATB4 //pin LCD data 4
51 #define lcd_D5 LATBbits.LATB5 //pin LCD data 5
52 #define lcd_D6 LATBbits.LATB6 //pin LCD data 6
53 #define lcd_D7 LATBbits.LATB7 //pin LCD data 7
54
55 #define lcd_line1 0x80 //line1 pos1 ram and display character position
56 #define lcd_line2 0xc0 //line2 pos1 ram and display character position
57 #define lcd_line3 0x90 //line3 pos1 ram and display character position
58 #define lcd_line4 0xd0 //line4 pos1 ram and display character position
59
60 void LCD_EN(void);
61 void LCD_INIT(void);
62 void LCD_CLEAR(void);
63 void LCD_CLR(void);
64 void LCD_HOME(void);
65 void LCD_NIBBLE(unsigned char c);
66 void LCD_WRITE(unsigned char c);
67 void LCD_CMD(char c);
68 void LCD_PUTCH(char c);
69 void LCD_PUTS(const char * s);
70 void LCD_GOTO(char line, char pos);
71 void LCD_PUTUN(unsigned int n);
72 void LCD_PUTSN(signed int n);
73 void LCD_CUSTOMCHAR(unsigned char pos,
74 unsigned char byte0,
75 unsigned char byte1,
76 unsigned char byte2,
77 unsigned char byte3,
78 unsigned char byte4,
79 unsigned char byte5,
80 unsigned char byte6,
81 unsigned char byte7);
82
83
84 void LCD_EN(void)
85 {
86 lcd_EN=1;
87 __delay_us(5);
88 lcd_EN=0;
89 }
90
91 void LCD_INIT(void)
92 {
93 unsigned int i;
94
95 lcd_RS=0; //instruction mode selected
96 for(i=0;i<100;i++) __delay_ms(5); //delay after power on (ONLY FOR 5V Vdd!!)
97
98 lcd_D4=1;
99 lcd_D5=1;
100 lcd_D6=0;
101 lcd_D7=0;
102 LCD_EN();
103 __delay_ms(6);
104
105 LCD_EN();
106 __delay_us(150);
107 LCD_EN();
108 __delay_ms(6); //delays for internal logic
109
110 lcd_D4=0;
111 lcd_D5=1;
112 lcd_D6=0;
113 lcd_D7=0;
114 LCD_EN();
115 __delay_us(100); //4bit mode selected
116
117 LCD_WRITE(0b00101000); //4bit interface - 2 lines display - font 5x8
118 LCD_WRITE(0b00001000); //display OFF - cursor not visible - cursor not blinking
119 LCD_CLEAR(); //clear display
120 LCD_WRITE(0b00001100); //display ON - cursor not visible - cursor not blinking
121 LCD_WRITE(0b00000110); //entry mode: display not shifted - DDRAM Add Count
increments
122 }
123
124 void LCD_CLEAR(void)
125 {
126 lcd_RS=0;
127 LCD_CMD(0x00); //clear display and address counter
128 __delay_ms(1);
129 }
130
131 void LCD_CLR(void)
132 {
133 lcd_RS=0;
134 LCD_CMD(0x01); //clears display and address counter
135 __delay_ms(10);
136 }
137
138 void LCD_HOME(void)
139 {
140 lcd_RS=0;
141 LCD_CMD(0x02); //only address counter=0
142 __delay_ms(1);
143 }
144
145 void LCD_NIBBLE(unsigned char c) //write nibble for LCD. useful for 4bit
mode-interface
146 {
147 if (c & 0b10000000) //if D7==1
148 lcd_D7=1;
149 else lcd_D7=0;
150
151 if (c & 0b01000000) //if D6==1
152 lcd_D6=1;
153 else lcd_D6=0;
154
155 if (c & 0b00100000) //if D5==1
156 lcd_D5=1;
157 else lcd_D5=0;
158
159 if (c & 0b00010000) //if D4==1
160 lcd_D4=1;
161 else lcd_D4=0;
162 //masks to identifier single bits
163 LCD_EN();
164 }
165
166 void LCD_WRITE(unsigned char c)
167 {
168 LCD_NIBBLE(c); //write on lcd the most significant nibble
169 c=c << 4; //shift the nibble
170 LCD_NIBBLE(c); //write on lcd the less siginificant nibble
171 __delay_us(50);
172 }
173
174 void LCD_CMD(char c)
175 {
176 lcd_RS=0; //write a command
177 LCD_WRITE(c); //send to writing routine
178 }
179
180 void LCD_PUTCH(char c)
181 {
182 lcd_RS=1; //write a character
183 LCD_WRITE(c); //send to writing routine
184 }
185
186 void LCD_PUTS(const char * s)
187 {
188 lcd_RS=1; //write characters
189
190 while(*s)
191 {
192 LCD_WRITE(*s); //send the single character of the string
193 *s++; //select the next letter of string
194 }
195 }
196
197 void LCD_GOTO(char line, char pos)
198 {
199 switch(line)
200 {
201 case 1: LCD_CMD((lcd_line1-1)+pos); //set position on line 1
202 break;
203 case 2: LCD_CMD((lcd_line2-1)+pos); //set position on line 2
204 break;
205 case 3: LCD_CMD((lcd_line3-1)+pos); //set position on line 2
206 break;
207 case 4: LCD_CMD((lcd_line4-1)+pos); //set position on line 2
208 break;
209 } // " (lcd_line1-1)+pos " function: lcd_line1 set the cursor to first position
210 } // thanks " -1 " it decreased the position, so if pos=1 the cursor is on the first
pos
211
212 void LCD_PUTUN(unsigned int n)
213 {
214 unsigned char i,t,wrt=0;
215 unsigned int m;
216
217 for(i=0;i<4;i++)
218 {
219 switch(i)
220 {
221 case 0: m=10000; break;
222
223 case 1: m=1000; break;
224
225 case 2: m=100; break;
226
227 case 3: m=10;
228 }
229 t=n/m;
230
231 if((wrt)||(t!=0))
232 {
233 LCD_PUTCH(t+'0'); //coverts to ASCII code
234 wrt=1;
235 }
236 n=n-(t*m);
237 }
238 LCD_PUTCH(n+'0');
239 }
240
241 void LCD_PUTSN(signed int n)
242 {
243 if(n<0)
244 {
245 LCD_PUTCH('-');
246
247 n=n*(-1);
248 }
249 LCD_PUTUN(n);
250 }
251
252 void LCD_CUSTOMCHAR(unsigned char pos,
253 unsigned char byte0,
254 unsigned char byte1,
255 unsigned char byte2,
256 unsigned char byte3,
257 unsigned char byte4,
258 unsigned char byte5,
259 unsigned char byte6,
260 unsigned char byte7)
261 {
262 LCD_CMD(0b00001000); //display off
263 LCD_CLEAR();
264 LCD_CMD(64+(pos*8)); //go to the right CGRAM location
265 LCD_PUTCH(byte0);
266 LCD_PUTCH(byte1);
267 LCD_PUTCH(byte2);
268 LCD_PUTCH(byte3);
269 LCD_PUTCH(byte4);
270 LCD_PUTCH(byte5);
271 LCD_PUTCH(byte6);
272 LCD_PUTCH(byte7);
273 LCD_CMD(0b00001100); //display settings
274 //display ON - cursor not visible - cursor not blinking
275 }
1 /* File: PWMfunctions.h
2 * Author: Biohazard
3 * Created on Marzo 2015
4 *******************************************************************************
5 PWM ROUTINES FOR:
6 - Register and Modules CCPx Setup
7 - Writing Duty Cycle Value
8 *******************************************************************************
9 -- Based and tested on PIC18F4525
10 *******************************************************************************
11 PWM ROUTINES DESCRIPTION:
12
13 - PWMsetup(char) -------------> Initialize PWM registers and modules.
14 It needs the PR2 value for PWM Frequency
15
16 - PWMduty1(unsigned int) ----> Write the value of Duty Cycle(DC) on CCP1
17
18 - PWMduty2(unsigned int) ----> Write the value of Duty Cycle(DC) on CCP2
19
20 - PWMdutyx(unsigned int,unsigned int) --> Write both DC (on CCP1 and CCP2)
21 *******************************************************************************
22 PWM Duty Cycle =(CCPR1L:CCP1CON<5:4>) • TOSC • (TMR2 Prescale Value)
23
24 periodo PWM =[(PR2)+1]*4*Tosc*(TMR2 prescale value)
25 *******************************************************************************/
26 #define PWM1 LATCbits.LATC2 //ccp1
27 #define PWM2 LATCbits.LATC1 //ccp2
28
29 void PWMsetup(char pr2);
30 void PWMduty1(unsigned int duty1);
31 void PWMduty2(unsigned int duty2);
32 void PWMdutyx(unsigned int duty1,unsigned int duty2);
33
34 void PWMsetup(char pr2)
35 {
36 CCP1CON=0; //reset CCP1 module
37 CCP2CON=0; //reset CCP2 module
38
39 PR2=pr2; //set the PWM frequency
40
41 PWMduty1(0); //Duty=0% on CPP1
42 PWMduty2(0); //Duty=0% on CPP2
43
44 T2CON=0b00000110; //setup of TMR2 register
45 /*
46 * bit 7 --> None
47 * bit 6-5-4-3 --> Timer2 Output Postscale - value 1:1
48 * bit 2 --> Timer2 On
49 * bit 1-0 --> Timer2 Clock Prescale - value 16
50 */
51
52 CCP1M3=1; CCP1M2=1; CCP1M1=0; CCP1M0=0; //PWM mode (CCP1)
53 CCP2M3=1; CCP2M2=1; CCP2M1=0; CCP2M0=0; //PWM mode (CCP2)
54 }
55
56 void PWMduty1(unsigned int duty1)
57 {
58 DC1B0=0x01 & duty1; //mask for the first bit LSB
59 DC1B1=0x01 & (duty1>>1); //mask for the second LSB
60 CCPR1L=duty1>>2; //translation for the 8 MSB
61 }
62
63 void PWMduty2(unsigned int duty2)
64 {
65 DC2B0=0x01 & duty2; //mask for the first bit LSB
66 DC2B1=0x01 & (duty2>>1); //mask for the second LSB
67 CCPR2L=duty2>>2; //translation for the 8 MSB
68 }
69
70 void PWMdutyx(unsigned int duty1,unsigned int duty2)
71 {
72 PWMduty1(duty1);
73 PWMduty2(duty2);
74 }
75
1 /* File: ULTRASONICfunctions.h
2 * Author: Biohazard
3 * Created on Marzo 2015
4 *******************************************************************************
5 ULTRASONIC SENSOR ROUTINES FOR:
6 - Send start command to trigger pin
7 - Read the distance
8 *******************************************************************************
9 -- For HC-SR04 Ultrasonic Sensor (2x)
10 -- Based and tested on PIC18F4525
11 *******************************************************************************
12 ULTRASONIC SENSOR ROUTINES DESCRIPTION:
13
14 - ULTRApulse1() ------> Sends the start command to sensor (start pulse)
15
16 - int ULTRAdist1() ---> Reads the answer of sensor and calculates the distance
17
18 - ULTRApulse2() ------> Sends the start command to sensor (start pulse)
19
20 - int ULTRAdist2() ---> Reads the answer of sensor and calculates the distance
21
22 - void ULTRAset() ---> Sets Timer1 registers. Call it at the beginning
23 *******************************************************************************/
24 #include <htc.h>
25
26 #define trigger1 LATCbits.LATC3
27 #define echo1 PORTCbits.RC0
28 #define trigger2 LATDbits.LATD1
29 #define echo2 PORTDbits.RD0
30
31 void ULTRApulse1(void);
32 void ULTRApulse2(void);
33 unsigned int ULTRAdist1(void);
34 unsigned int ULTRAdist2(void);
35 void ULTRAset(void);
36
37 void ULTRApulse1(void) //send the starting pulse to sensor
38 {
39 trigger1=1;
40 __delay_us(10);
41 trigger1=0;
42 }
43
44 void ULTRApulse2(void) //send the starting pulse to sensor
45 {
46 trigger2=1;
47 __delay_us(10);
48 trigger2=0;
49 }
50
51 unsigned int ULTRAdist1(void)
52 {
53 unsigned int time=0,dist=0,i;
54
55 for(i=0;i<10;i++) __delay_ms(10);
56
57 ULTRApulse1();
58
59 while(1)
60 {
61 if(echo1==1)
62 {
63 TMR1L=0; TMR1H=0; //timer1 = 0
64
65 while(1)
66 {
67 if(echo1==0) //when the sensor's answer is finished
68 {
69 time=(TMR1H<<8)+TMR1L; //copy timer1 value into time variable
70 //time contains the echo answer in uS
71 dist=time/58; //find the distance as cm
72 return dist;
73 }
74
75 if(((TMR1H<<8)+TMR1L)==23200) //when distance reach the max=400cm,
76 { //return to main
77 ULTRApulse1();
78 while(1)
79 {
80 if(echo1==1)
81 {
82 TMR1L=0; TMR1H=0;
83 while(1)
84 {
85 if(echo1==0)
86 {
87 time=(TMR1H<<8)+TMR1L;
88 dist=time/58;
89 return dist;
90 }
91
92 if(((TMR1H<<8)+TMR1L)==23200)
93 {
94 TMR1L=0; TMR1H=0;
95 return 400;
96 }
97 }
98 }
99 }
100 }
101 }
102 }
103 }
104 }
105
106 unsigned int ULTRAdist2(void)
107 {
108 unsigned int time=0,dist=0,i;
109
110 for(i=0;i<10;i++) __delay_ms(10);
111
112 ULTRApulse2();
113
114 while(1)
115 {
116 if(echo2==1)
117 {
118 TMR1L=0; TMR1H=0; //timer1 = 0
119
120 while(1)
121 {
122 if(echo2==0) //when the sensor's answer is finished
123 {
124 time=(TMR1H<<8)+TMR1L; //copy timer1 value into time variable
125 //time contains the echo answer in uS
126 dist=time/58; //find the distance as cm
127 return dist;
128 }
129
130 if(((TMR1H<<8)+TMR1L)==23200) //when distance reach the max=400cm,
131 { //return to main
132 TMR1L=0; TMR1H=0;
133 return 400;
134 }
135 }
136 }
137 }
138 }
139
140 void ULTRAset(void)
141 {
142 T1CON=0b00100001; //setup of timer1 register
143 /*
144 * bit 7 ----> 8-Bit Read/Write Mode Enabled
145 * bit 6 ----> Timer1 System Clock Status (another source)
146 * bit 5-4 --> Timer1 Input Clock Prescale - value 1:4
147 * bit 3 ----> Timer1 Oscillator Enable Control bit - disabled
148 * bit 2 ----> Timer1 External Clock Input Synchronization Control bit
149 Ignored
150 * bit 1 ----> Timer1 Clock Source - Internal clock (FOSC/4)
151 * bit 0 ----> Timer1 On bit - ON
152 *
153 * TMR1 count 1uS
154 */
155 }
156