// BAROGRAPH ELECTRONIQUE AVEC LCD GRAPHIQUE ANGLAIS // ****************************************************************** // Jacques Brodeur 1er aout 01, 18 nov 01, 1 avril 02 // // Utiliser un PIC16F876 a 4.194304 mHz // // PIC conections LCD LCD GRAPHIQUE 160 X 128 points // patte patte // 21 RB0 = LCD D0 12 // 22 RB1 = LCD D1 13 // 23 RB2 = LCD D2 14 // 24 RB3 = LCD D3 15 // 25 RB4 = LCD D4 16 // 26 RB5 = LCD D5 17 // 27 RB6 = LCD D6 18 // 28 RB7 = LCD D7 19 // // 15 RC4 = LCD /WR 6 // 16 RC5 = LCD /RD 7 // 17 RC6 = LCD /CE 8 // 18 RC7 = LCD C//D 9 // // FG 1 Frame Ground // VSS 2 Signal Ground // VCC 3 +5Volt // VADJ 4 CT du pot de 10K // VEE 5 -21Volt // /HALT 10 // /RESET 11 // NC 20 // // Plage de temperature: -50 @ +50 Celsius // plage de pression: 95.0 @ 105.0 kPascals /* #ifdef DEBUG// Utiliser pour deverminer avec un terminal RS232 printf("\r\n"); #endif */ // *********************** Directives ***************************** #include <16f876.h> #device adc=10 #include #fuses XT,NOWDT,PROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT #use delay (clock=4194304) // * * * * * Commenter pour enlever le deverminage * * * * * //#use rs232 (baud=9600, xmit=PIN_A2) //#define DEBUG // * * * * * * * * * * * * * * * #use fast_io(a) #use fast_io(b) #use fast_io(c) #define WR PIN_C4 // pattes de commande du LCD #define RD PIN_C5 #define CE PIN_C6 #define CD PIN_C7 #byte porta = 5 #byte portb = 6 #byte portc = 7 // ******************* Declaration des variables ******************* int1 flag_1sec; //variables 1 bit flags int1 flag_30min; int1 flag_1hre; int1 flag_clignote; int1 flag_ete_hiver=1; int8 i,j,z,y; // -------------- variables de 8 bits int8 compte_interrupt=8,secondes=0,minutes=0,heures=0,jour=0; int8 num_hres_courantes=0; int8 temporaire; int8 stat; //status du lcd int16 resultat; // variables de 16 bits int16 caseMem; signed int8 i8_temp1,i8_temp2; int8 point5; float press; // variables de 32 bits int16 debut_ligne; int16 debut_graph; signed int16 aff_graph; int16 u; int16 t; int8 ligne_graph[20];//une ligne de graphique //****************** Declaration des constants ******************** char const journee[22]="SunMonTueWedThuFriSat";//DimLunMarMerJeuVenSam int8 const midi_minuit[20]={0X00,0X1E,0X25,0X29,0X1E,0X00,0X00, 0X11,0X3F,0X01,0X00,0X11,0X23,0X25,0X19,0X00,0X1E,0X25,0X29,0X1E}; // ******************* Prototypes des fonctions ******************* void pic_ini(void); void lcd_ini(void); void ecri_lcd_byte(int data8);//--------------LCD-------------- void ecri_lcd_mot(long data16); void ecri_lcd_cmde(int cmde); void ecri_lcd_ascii(char data8); void lireStatus(void); void clearScreen(void); int8 lire_lcd_byte(void); void set_heure(void); void imprimer_ecran(void); void lire_capteurs(void); void afficher_temp_press(void); void decaler_graph(void); void rehausser_graph(void);//--------affichage du graph---------- void faire_lignes(void); void hres_courantes(void); void int_horloge(void);// Routine de l'interruption de l'horloge void reset_dallas(void); void write8_dallas(int8 data); signed int16 read16_dallas(void); strg_pullup_dallas(int1 on_off); // // ************************** fonctions ***************************** // void pic_ini(void) { for(i=0;i<18;i++)ligne_graph[i]=0xff; setup_adc_ports(RA0_ANALOG);// ADC ini RA1_RA3_ setup_adc(ADC_CLOCK_INTERNAL); porta=0; portb=0; portc=0; set_tris_a(0b11111111);// port A, entree set_tris_b(0x00);// PORT B et C direction entree set_tris_c(0x0f);// flag_1sec=0; //variables 1 bit flags flag_30min=0; flag_1hre=0; flag_clignote=1; set_rtcc(0); setup_counters(rtcc_internal,rtcc_div_256); enable_interrupts(INT_RTCC); enable_interrupts(global); } //------------------------------------------------------ void lcd_ini(void)// LCD setup { OUTPUT_HIGH(WR); OUTPUT_HIGH(RD); OUTPUT_HIGH(CE); OUTPUT_HIGH(CD); OUTPUT_HIGH(PIN_A4); delay_ms(100); ecri_lcd_mot(0x0000);// Address 0000h 0000d ecri_lcd_cmde(0x40);// Text home address ecri_lcd_mot(0x0014);// 20 colonnes ecri_lcd_cmde(0x41);// Text area set ecri_lcd_mot(0x0400);// Address 0400h 1024d ecri_lcd_cmde(0x42);// Graphic home address ecri_lcd_mot(0x0014);// 20 colonnes ecri_lcd_cmde(0x43);// Graphic area set ecri_lcd_cmde(0x80);// Mode set. OR car gen Rom ecri_lcd_cmde(0x9C);// Text on, graphic on } //-------------------------------- void ecri_lcd_byte(int data8)// -Charger 1 DATA 8 bits dans le LCD- { lireStatus(); portb=data8; OUTPUT_LOW(CD);// Data OUTPUT_LOW(WR); OUTPUT_LOW(CE); delay_cycles(1); OUTPUT_HIGH(CE); OUTPUT_HIGH(WR); ecri_lcd_cmde(0xC0); //incrementer la position } //------------------------------- void ecri_lcd_mot(long data16)// Charger 1 DATA 16 bits dans le LCD- { lireStatus(); portb=(data16 & 0xFF); OUTPUT_LOW(CD);// Data OUTPUT_LOW(WR);// Ecrire OUTPUT_LOW(CE);// Clancher delay_cycles(1); OUTPUT_HIGH(CE); OUTPUT_HIGH(WR); lireStatus(); portb=(data16>>8); OUTPUT_LOW(CD); OUTPUT_LOW(WR); OUTPUT_LOW(CE); delay_cycles(1); OUTPUT_HIGH(CE); OUTPUT_HIGH(WR); } //-------------------------------------- void ecri_lcd_cmde(int cmde)//Charger 1 byte de commande dans le LCD- { lireStatus(); portb=(cmde); OUTPUT_HIGH(CD);// Commande OUTPUT_LOW(WR); OUTPUT_LOW(CE); delay_cycles(1); OUTPUT_HIGH(CE); OUTPUT_HIGH(WR); } //-------------------------------- void ecri_lcd_ascii(char data8)// -Charger 1 DATA 8 bits dans le LCD- { lireStatus(); portb=data8-0x20; OUTPUT_LOW(CD);// Data OUTPUT_LOW(WR); OUTPUT_LOW(CE); delay_cycles(1); OUTPUT_HIGH(CE); OUTPUT_HIGH(WR); ecri_lcd_cmde(0xC0); //incrementer la position } //--------------------------------------- int8 lire_lcd_byte(void) { int8 data; lireStatus(); ecri_lcd_cmde(0xC1); //incrementer la position lireStatus(); set_tris_b(0xFF);// entree OUTPUT_LOW(CD);// Data OUTPUT_LOW(RD); OUTPUT_LOW(CE); delay_cycles(2); data=portb; OUTPUT_HIGH(CE); OUTPUT_HIGH(RD); set_tris_b(0x00);//sortie return(data); } //------------------------------------------ void lireStatus(void) { set_tris_b(0xFF); // portB en entree OUTPUT_HIGH(CD); //Commande OUTPUT_LOW(RD); do { OUTPUT_LOW(CE); delay_cycles(2); stat=portb; OUTPUT_HIGH(CE); delay_cycles(2); } while(stat&&0b00000011==0); //attendre que STA0 et STA1 soient a 1 OUTPUT_HIGH(RD); set_tris_b(0x00); //portB en sortie } // ------------------------------------------------------------------ void reset_dallas(void) { output_low(PIN_A1); set_tris_A(0b00111101);//port A bit1 sortie delay_us(700); set_tris_A(0b00111111);//port A bit1 entree delay_us(600);//65us pour lire presence et 500us attente } // ---------------------------------- strg_pullup_dallas(int1 on_off) { if(on_off) { output_high(PIN_A1); set_tris_A(0b00111101);//port A bit1 sortie } else set_tris_A(0b00111111);//port A bit1 entree } // ----------------------------------- void write8_dallas(int8 data) { int8 shiftbit; shiftbit=8; do { if(shift_right(&data,1,0))//write 1 { output_low(PIN_A1); set_tris_A(0b00111101);//port A bit1 sortie delay_us(10); set_tris_A(0b00111111);//bit1 entree delay_us(60); } else //write 0 { output_low(PIN_A1); set_tris_A(0b00111101);//port A bit1 sortie delay_us(70); set_tris_A(0b00111111);//bit1 entree } shiftbit--; } while(shiftbit>0); } // -------------------------------- signed int16 read16_dallas(void) { signed int16 temp_bin=0; int8 shiftbit; for(shiftbit=16;shiftbit>0;shiftbit--) { output_low(PIN_A1); set_tris_A(0b00111101);//port A bit1 sortie //delay_us(1); set_tris_A(0b00111111);//bit1 entree delay_us(5); shift_right(&temp_bin,2,input(PIN_A1)); delay_us(80); } return(temp_bin); } //------------------------------------------------------------------ void clearScreen(void) { ecri_lcd_mot(0x0000);// Address 0000h ecri_lcd_cmde(0x24);// Set Text address pointer for(caseMem=0;caseMem<0x1FFF;caseMem++) { ecri_lcd_byte(0x00); //ecri_lcd_cmde(0xC0);// Incremente le pointeur d'addresse } ecri_lcd_mot(0x0000);// Address 0000h - debut de l'ecran ecri_lcd_cmde(0x24);// Set Text address pointer } //----------------------------------- void set_heure(void)// mettre l'horloge a l'heure { disable_interrupts(global); do { switch((~portc)&0x0F) { case 0x01://reserve break; case 0x02://Avancer le jour ++jour; if(jour>=7)jour=0; break; case 0x04://Avancer les heures ++heures; if(heures>=24)heures=0; break; case 0x08://Avancer les minutes ++minutes; if(minutes>=60)minutes=0; break; default://2 boutons en meme temps break; } ecri_lcd_mot(20);// 2ie ligne ecri_lcd_cmde(0x24);// Set Text address pointer i=jour*3; for(j=3;j>0;j--) { printf(ecri_lcd_ascii,"%c",journee[i]); i++; } printf(ecri_lcd_ascii," %02u:%02u",heures,minutes); delay_ms(500); } while(input(PIN_A5)==0); //ecri_lcd_mot(0x00A0);// 9ie ligne //ecri_lcd_cmde(0x24);// Set Text address pointer //printf(ecri_lcd_ascii," "); secondes=0; enable_interrupts(global); } //---------------------------------- imprimer_ecran() { ecri_lcd_mot(0x0000);// 7ie ligne ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"DAY TIME TEMP PRESS");//DAY TIME TEMP PRESS delay_ms(4); ecri_lcd_mot(1364);// Address ecri_lcd_cmde(0x24);// Set graphic address pointer for(i=40;i!=0;i--) ecri_lcd_byte(0xFF); //faire 2 lignes } //------------------------------------- lire_capteurs()// Lire les capteurs sur l'ADC { set_adc_channel(0);//preparer la lecture de pression strg_pullup_dallas(false);//enlever l'alimentation sur DS18S20 delay_us(2); reset_dallas();//reset lecture prend 4.5 mSec write8_dallas(0xCC);//command skip rom write8_dallas(0xBE);//command read i8_temp1=read16_dallas();//lire 2 bytes en sauver une reset_dallas();// commande prend 3 mSec write8_dallas(0xCC);//command skip rom write8_dallas(0x44);//command aquire temperature strg_pullup_dallas(true);//appliquer l'alimentation pour une seconde //**************************************************************** i8_temp2=i8_temp1/2; if(i8_temp1%2)point5=5; else point5=0; //**************************************************************** if(i8_temp2 <=-15) flag_ete_hiver=0;// changer pour hiver -35 @ +10 if(i8_temp2>=15) flag_ete_hiver=1;// changer pour ete -15 @ +35 if(flag_ete_hiver) { ecri_lcd_mot(60); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"+35c"); ecri_lcd_mot(120); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"+20c"); ecri_lcd_mot(220); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii," 0c "); ecri_lcd_mot(280); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"-15c"); } else { ecri_lcd_mot(60); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"+15c"); ecri_lcd_mot(120); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii," 0c "); ecri_lcd_mot(220); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"-20c"); ecri_lcd_mot(280); ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"-35c"); } resultat=read_adc(); press=resultat/102.3;press=press+95; } //------------------------------- afficher_temp_press()// afficher temp et pression { ecri_lcd_mot(0x0014);// debut de la 2ie ligne 20 ecri_lcd_cmde(0x24);// Set Text address pointer i=jour*3; for(j=3;j>0;j--) { printf(ecri_lcd_ascii,"%c",journee[i]); i++; } printf(ecri_lcd_ascii," %02u:%02u",heures,minutes); //******************* if(i8_temp1>=20)printf(ecri_lcd_ascii," %d.%u ",i8_temp2,point5); else if(i8_temp1>=0)printf(ecri_lcd_ascii," %d.%u ",i8_temp2,point5); else if(i8_temp1==-1)printf(ecri_lcd_ascii," -0.%u ",point5); else if (i8_temp1<=-20)printf(ecri_lcd_ascii,"%d.%u ",i8_temp2,point5); else printf(ecri_lcd_ascii," %d.%u ",i8_temp2,point5); //****************** if(press<100)printf(ecri_lcd_ascii," %4.1f",press); else printf(ecri_lcd_ascii,"%5.1f",press); if(flag_clignote==1) { ecri_lcd_mot(26);// 2ie ligne 3ie car ecri_lcd_cmde(0x24);// Set Text address pointer printf(ecri_lcd_ascii,"*"); } flag_clignote=flag_clignote-1; } //--------------------------------------- decaler_graph() { debut_ligne=1424;// 2ie ligne adresse de depart du graphique for (i=1;i<=108;i++) { ecri_lcd_mot(debut_ligne);// Set Text address pointer ecri_lcd_cmde(0x24); // au debut de la ligne for(j=20;j>0;j--) // chercher une ligne { ligne_graph[j-1]=lire_lcd_byte();//chercher une byte } shift_left(ligne_graph,20,0);//decaler a gauche une bit ecri_lcd_mot(debut_ligne);// Set Text address pointer ecri_lcd_cmde(0x24); // au debut de la ligne for(j=20;j>0;j--)// retourner une ligne { ecri_lcd_byte(ligne_graph[j-1]);//retourner une byte } debut_ligne=debut_ligne+20;//ajouter 20 adresse } } //--------------------------------------- rehausser_graph()// afficher le graphique temp press { //standardiser entre 0 et 100 if(flag_ete_hiver==0)aff_graph=(i8_temp1)+70;//echelle +15 a -35 degrees ou else aff_graph=(i8_temp1)+30; //echelle +35 a -15 degrees if(aff_graph<0)aff_graph=0;//min if(aff_graph>100)aff_graph=100;//max aff_graph=100-aff_graph; aff_graph=aff_graph*20; aff_graph=aff_graph+1443; ecri_lcd_mot(aff_graph); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 aff_graph=press*10; aff_graph=aff_graph-950; if(aff_graph<0)aff_graph=0;//min if(aff_graph>100)aff_graph=100;//max aff_graph=100-aff_graph; aff_graph=aff_graph*20; aff_graph=aff_graph+1443; ecri_lcd_mot(aff_graph); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 ecri_lcd_mot(aff_graph+20); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } //----------------------------------- faire_lignes()// faire les lignes de temps et d'amplitude { switch(heures) { case 00: num_hres_courantes=0;//reset pour heures courantes aff_graph=1443; for(u=0;u<=2000;u=u+40) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } break; case 06: num_hres_courantes=6;//reset pour heures courantes aff_graph=1443; for(u=0;u<=2000;u=u+200) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } break; case 12: num_hres_courantes=10;//reset pour heures courantes aff_graph=1443; for(u=0;u<=2000;u=u+100) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } break; case 18: num_hres_courantes=16;//reset pour heures courantes aff_graph=1443; for(u=0;u<=2000;u=u+200) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } break; default: break; } if((heures&01)==0) // 4 barres horizontales foncees de zero { aff_graph=1443; for(u=0;u<=600;u=u+600) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } aff_graph=aff_graph+1400; for(u=0;u<=600;u=u+600) { ecri_lcd_mot(aff_graph+u); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer ecri_lcd_cmde(0xF8); // Set bit 0 } } } //---------------------------------- hres_courantes() { if((heures>=22)||(heures<=02)) { temporaire=midi_minuit[num_hres_courantes]; aff_graph=3583; for(u=0;u<6;u++) { ecri_lcd_mot(aff_graph-(20*u)); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer if(bit_test(temporaire,u)) ecri_lcd_cmde(0xF8); // Set bit 0 else ecri_lcd_cmde(0xF0); // clear bit 0 } num_hres_courantes++; } if((heures>=10)&&(heures<=14))//MIDI { temporaire=midi_minuit[num_hres_courantes]; aff_graph=3583; for(u=0;u<6;u++) { ecri_lcd_mot(aff_graph-(20*u)); // Address ecri_lcd_cmde(0x24); // Set graphic address pointer if(bit_test(temporaire,u)) ecri_lcd_cmde(0xF8); // Set bit 0 else ecri_lcd_cmde(0xF0); // clear bit 0 } num_hres_courantes++; } } //----------------------------------- #int_rtcc//-----------routine d'interruption de l'horloge--------- void int_horloge(void) { if(--compte_interrupt==0) { compte_interrupt=16;//16 flag_1sec=1; ++secondes;//secondes=60;// } if(secondes>=60) { secondes=0; ++minutes; if(minutes==30)flag_30min=1; } if(minutes>=60) { minutes=0; ++heures; flag_1hre=1; } if(heures==24) { heures=0; ++jour; } if(jour>=7) { jour=0; } } // // ******************** Programme principal *********************** // main() { pic_ini(); lcd_ini(); DELAY_MS(200); clearScreen(); imprimer_ecran();//faire le fond de l'ecran do//-------------------- Boucle sans fin -------------------- { if(input(PIN_A5)==0)// Tester la sw pour placer heure { delay_ms(25);//debounce if(input(PIN_A5)==0)set_heure();//OK debounce fait } if(flag_1sec==1)//--------faire toutes les secondes---- { lire_capteurs();// lire les capteurs afficher_temp_press(); flag_1sec=0; } if(flag_30min==1)//afficher graph toutes les 1/2 heure- { decaler_graph(); rehausser_graph(); hres_courantes(); flag_30min=0; } if(flag_1hre==1)//afficher graph toutes les heures { decaler_graph(); rehausser_graph(); faire_lignes(); // faire lignes verticales hres_courantes(); flag_1hre=0; } } while(1);// ----------------Toujour tourner------------------ } // ***************************** fin ******************************