/******************************************************************************
* Fichier: Programme de la centrale de navigation
* auteur: Hernot Sophie
* date: 19 Fevrier 2020
******************************************************************************/
#include <xc.h> //déclaration des registres du pic utilisé
#include <stdio.h>
#include <stdlib.h>
#include "peripherique.h" //déclaration des fonctions pilotant les peripheriques
/* declaration des variables */
char fonction,sec,min,heu,sectempo,cen,diz,uni,transfert=1,capteur,altempmin,altempmax,alvitmax,ret,unitdir,unitcap,unitvitesse,reglage;
int temperature,temperaturebrut,temperaturefloat,vitesse,vitessefloat,i,t,inter=0,sup=1,inf=0,menusup=3,menuinter=3;
long int direction,directionbrut,directionfloat,VAR,VARbrut;
unsigned char j=0,CRC,test,chaine_transfert[50];
/* declaration des boutons */
#define valid PORTBbits.RB4
#define retour PORTBbits.RB3
#define plus PORTBbits.RB2
#define moins PORTBbits.RB1
/* définition */
#define _XTAL_FREQ 4000000
#define led PORTEbits.RE2
#define lcd_en LATEbits.LATE1 // LCD enable
#define lcd_rs LATEbits.LATE0 // bit permettant la selection donnée/instruction
/* declaration des fonctions */
extern void aff_trans(char);
extern void trans_on_off(void);
extern void unit_direction(void);
extern void unit_vitesse(void);
extern void unit_cap(void);
extern void test_transfert(void);
extern void alarme_temp(void);
extern void alarme_vitesse(void);
extern void regl_tempo(void);
extern void affiche_heure(void);
extern void affiche_temperature(void);
extern void affiche_vitesse_vent(void);
extern void affiche_direction_vent(void);
extern void delay_spe(int);
void regl_heure(void);
void Tx(unsigned char Temp);
void transferer(void);
void tempo (unsigned char i){unsigned char j;for (i=0;i<10;i++)__delay_ms(100);}
void acquisition_temperature (void);
void acquisition_direction_vent (void);
void acquisition_vitesse_vent (void);
void main(void)
{
TRISA=0xFF; // Pour les capteurs
TRISB=0xFF; // Pour les boutons poussoirs
TRISC=0xC0; // TRISC:7 et TRISC:6 nécessaires pour bon fonctionnement liaison série
TRISD=0x00;
ADCON0=0x01; // Active les conversions analogique-numérique pour la température et l'anémomètre
ADCON1=0x0f; //Carte projet : 0b00011011; Carte TEST : 0x0f;
ADCON2=0b00010100;
lcd_init(); // Initalisation de l'écran LCD
unitvitesse=0; // l'unité de la vitesse du vent est en kh/m par défaut
unitdir=0; // l'unité de la direction du vent est en degré par défaut
unitcap=0; // l'unité du cap est en degré par défaut
capteur=0; // capteurs classiques par défaut
T1CON=0x79; // activation de TIMER1 pour l'horloge
TMR1H = 0x80;// Préchargement pour débordement après 1s
TMR1L = 0x00;
T1CON = 0b00001111; // Timer1 en compteur avec son oscillateur externe, prescaler = 1:1, et mise en route Timer1 (TMR1ON = 1)
T0CON=0xFF; // T08bit = 1 compteur 8 bits // TOCS=1 Horloge externe
TMR0L=0; //le compteur du timer0 = 0 pour défaut
TRISD=0x00;
TRISC = 0xC0;// TRISC:7 et TRISC:6 nécessaires pour bon fonctionnement liaison série
RCSTA = 0x90;// SPEN=1 ; RX9 = 0 ; CREN = 1; // pour la liaison série
TXSTA = 0x20;// TX9 = 0 ; TXEN = 1 ; SYNC = 0 ; BRGH = 0; // pour la liaison série
//BRG16 = 1; //9600 Bauds // pour une liaison série de 4800 bauds : //0x0C;
SPBRG = 25; // SPBRG = ((Fosc/vitesse)/64)-1 // SPBRG = ((4000000/4800)/64)-1
IPEN=1;
TMR1IP = 1;
TMR1IF = 0; // Drapeau de dépassement
TMR1IE = 1; // Active l'interruption quand le TIMER1 est overflow
TXIP = 0;
TXIF = 0; // Drapeau de dépassement --------------------------------ne fonctionne pas
GIEH = 1; // Autorisation interruptions non masquées
GIEL = 1; // Autorisation interruptions non masquées
/* declaration des parties fixes des trames pour l'ecran 4D */
chaine_transfert[0]=0x01;
chaine_transfert[1]=0x0F;
chaine_transfert[2]=0x03;
chaine_transfert[3]=0x00;
chaine_transfert[6]=0x01;
chaine_transfert[7]=0x0F;
chaine_transfert[8]=0x04;
chaine_transfert[9]=0x00;
chaine_transfert[12]=0x01;
chaine_transfert[13]=0x0F;
chaine_transfert[14]=0x00;
chaine_transfert[15]=0x00;
chaine_transfert[18]=0;
TRISD=0x00;
// while(1)
// {
// lcd_rs=0; //ecriture d'une donnée
// lcd_en=1;
// PORTD=0b01010101;
// __delay_ms(10);
// lcd_rs=1; //ecriture d'une donnée
// lcd_en=0;
// PORTD=0b10101010;
// __delay_ms(10);
// }
//}
while(1) /* menu 2.0 */
{
if(inter==0) /* menu principal (1er niveau) */
{
lcd_efface();
if(sup==1){lcd_aff_chaine("1. Affichage");lcd_write_inst(0xc1);lcd_aff_chaine("+ Transfert");}
if(sup==2){lcd_aff_chaine("2. Alarmes");}
if(sup==3){lcd_aff_chaine("3. Reglages");}
tempo(2);
if (plus==0){sup=sup+1;if (sup>menusup)sup=1;}
if (moins==0){sup=sup-1;if (sup<1)sup=menusup;}
if (valid==0){inter=1;if (sup==1)menuinter=5;if (sup==2)menuinter=2;if (sup==3)menuinter=7;}
}
if(inf==0 && inter!=0) /* sous menu (2eme niveau) */
{
lcd_efface();
if(sup==1 && inter==1){lcd_aff_chaine("1.1 Temperature");}
if(sup==1 && inter==2){lcd_aff_chaine("1.2 Vitesse");lcd_write_inst(0xc4);lcd_aff_chaine("du vent");}
if(sup==1 && inter==3){lcd_aff_chaine("1.3 Direction");lcd_write_inst(0xc4);lcd_aff_chaine("du vent");}
if(sup==1 && inter==4){lcd_aff_chaine("1.4 Tout affiche");lcd_write_inst(0xc0);lcd_aff_chaine("successivement");}
if(sup==1 && inter==5){lcd_aff_chaine("1.5 Tout affiche");lcd_write_inst(0xc0);lcd_aff_chaine("simultanement");}
if(sup==2 && inter==1){lcd_aff_chaine("2.1 Temperature");}
if(sup==2 && inter==2){lcd_aff_chaine("2.2 Vitesse");lcd_write_inst(0xc4);lcd_aff_chaine("du vent");}
if(sup==3 && inter==1){lcd_aff_chaine("3.1 Unite de la");lcd_write_inst(0xC0);lcd_aff_chaine("vitesse du vent");}
if(sup==3 && inter==2){lcd_aff_chaine("3.2 Unite de la");lcd_write_inst(0xC0);lcd_aff_chaine("direction du vent");}
if(sup==3 && inter==3){lcd_aff_chaine("3.3 Duree de");lcd_write_inst(0xC0);lcd_aff_chaine("la temporisation");}
if(sup==3 && inter==4){lcd_aff_chaine("3.4 Transfert");lcd_write_inst(0xc4);lcd_aff_chaine("On/Off");}
if(sup==3 && inter==5){lcd_aff_chaine("3.5 Reglage");lcd_write_inst(0xc4);lcd_aff_chaine("de l'heure");}
if(sup==3 && inter==6){lcd_aff_chaine("3.6 test de");lcd_write_inst(0xc4);lcd_aff_chaine("transfert");}
if(sup==3 && inter==7){lcd_aff_chaine("3.7 transfert");lcd_write_inst(0xc4);lcd_aff_chaine("ASCII");}
tempo(2);
if (plus==0){inter=inter+1;if (inter>menuinter)inter=1;}
if (moins==0){inter=inter-1;if (inter<1)inter=menuinter;}
if (valid==0)inf=1;
if (retour==0)inter=0;
}
if(inf==1) /* appel des fonctions demandés dans le menu */
{
lcd_efface();__delay_ms(20);ret=0;reglage=100;t=0;tempo(2);
if (sup==1)
{
while(retour!=0)
{
__delay_ms(1);
if(inter==1){lcd_write_inst(0xC0);affiche_temperature();lcd_write_inst(0x80);affiche_heure ();}
if(inter==2){lcd_write_inst(0xC0);affiche_vitesse_vent ();lcd_write_inst(0x80);affiche_heure ();}
if(inter==3){lcd_write_inst(0xC0);affiche_direction_vent ();lcd_write_inst(0x80);affiche_heure ();}
if(inter==4)
{
for (int i=0;i<20;i++)__delay_ms(100);lcd_efface();affiche_temperature ();
for (int i=0;i<20;i++)__delay_ms(100);lcd_efface();affiche_vitesse_vent ();
for (int i=0;i<20;i++)__delay_ms(100);lcd_efface();affiche_direction_vent ();
for (int i=0;i<20;i++)__delay_ms(100);lcd_efface();affiche_heure ();
tempo(2);
}
if(inter==5){
lcd_efface();
temperature=(50*temperaturebrut)/255;
lcd_aff_chiffre(temperature/10);lcd_aff_chiffre(temperature%10);lcd_aff_chaine("C ");
temperature=(50*temperaturebrut)/255;
lcd_aff_chiffre(temperature/10);lcd_aff_chiffre(temperature%10);lcd_aff_chaine("C ");
lcd_write_inst(0xc0);
VAR=VARbrut*314*36;
if(unitvitesse==0){vitesse=VAR/10000;lcd_aff_int(vitesse);lcd_aff_chaine("km/h ");} //Conversion en km/h
if(unitvitesse==1){vitesse=VAR/1852/10;lcd_aff_int(vitesse);lcd_aff_chaine("nds ");} //Conversion de la vitesse en noeuds
direction=(directionbrut*360)/256; //conversion en degrés
if(unitdir==1){lcd_aff_int(direction);lcd_aff_chaine("° ");}
if(unitdir==0) //affichage de la direction en points cardinaux
{
if(direction<=22 | direction>338){lcd_aff_chaine("S ");}
if(direction<=68 && direction>22){lcd_aff_chaine("S/W ");}
if(direction<=112 && direction>68){lcd_aff_chaine("W ");}
if(direction<=158 && direction>112){lcd_aff_chaine("N/W ");}
if(direction<=202 && direction>158){lcd_aff_chaine("N ");}
if(direction<=248 && direction>202){lcd_aff_chaine("N/E ");}
if(direction<=292 && direction>248){lcd_aff_chaine("E ");}
if(direction<=338 && direction>292){lcd_aff_chaine("S/E ");}
}
tempo(2);
}
}
}
if (sup==2)
{
if(inter==1){alarme_temp();}
if(inter==2){alarme_vitesse();}
}
if (sup==3)
{
if(inter==1){unit_vitesse();}
if(inter==2){unit_direction();}
if(inter==3){trans_on_off();}
if(inter==4){regl_heure();}
if(inter==5){test_transfert();}
}
sup=1;inter=0;inf=0;
}
}
}
/* Fonctions d'acquisition */
void acquisition_direction_vent (void)
{
ADCON0=0b00000011;
while((ADCON0&0x02)==0x02); // Attente de fin de conversion
directionbrut=1*ADRESH;
}
void acquisition_vitesse_vent (void)
{
TMR0ON=0;VARbrut=TMR0L;TMR0L=0;TMR0ON=1;
}
void acquisition_temperature (void)
{
ADCON0=0x07; //acquisition spécifique au thermomètre classique
while((ADCON0&0x02)==0x02); // Attente de fin de conversion
temperaturebrut=ADRESH;
}
/* Fonctions d'affichage */
void affiche_heure(void) // Affichage de l'heure
{
lcd_aff_chiffre(heu/10);lcd_aff_chiffre(heu%10);lcd_aff_chaine("h");
lcd_aff_chiffre(min/10);lcd_aff_chiffre(min%10);lcd_aff_chaine("m");
lcd_aff_chiffre(sec/10);lcd_aff_chiffre(sec%10);lcd_aff_chaine("s");
}
void affiche_temperature (void) // Calcul et affichage de la temperature
{
temperature=(50*temperaturebrut)/255;
lcd_aff_chaine("Temp:");lcd_aff_chiffre(temperature/10);lcd_aff_chiffre(temperature%10);lcd_aff_chaine(" degres ");
if(temperature>altempmax){TRISE2=0;}if(temperature<altempmin){TRISE2=0;}if(retour==0){ret=1;}
}
void affiche_vitesse_vent (void) // Calcul et affichage de la vitesse du vent
{
VAR=VARbrut*314*36;
if(unitvitesse==0){vitesse=VAR/10000;lcd_aff_int(vitesse);lcd_aff_chaine("km/h");} //Conversion en km/h
if(unitvitesse==1){vitesse=VAR/1852/10;lcd_aff_int(vitesse);lcd_aff_chaine("noeuds");} //Conversion de la vitesse en noeuds
if(vitesse>alvitmax){TRISE2=0;}if(retour==0){ret=1;} //Verification de la limite de l'alarme
}
void affiche_direction_vent (void) // Calcul et affichage de la direction du vent
{
direction=(directionbrut*360)/256; //conversion en degrés
if(unitdir==1){lcd_aff_int(direction);lcd_aff_chaine("degres");}
if(unitdir==0) //affichage de la direction en points cardinaux
{
if(direction<=22 | direction>338){lcd_aff_chaine("Sud");}
if(direction<=68 && direction>22){lcd_aff_chaine("Sud / Ouest");}
if(direction<=112 && direction>68){lcd_aff_chaine("Ouest");}
if(direction<=158 && direction>112){lcd_aff_chaine("Nord / Ouest");}
if(direction<=202 && direction>158){lcd_aff_chaine("Nord");}
if(direction<=248 && direction>202){lcd_aff_chaine("Nord / Est");}
if(direction<=292 && direction>248){lcd_aff_chaine("Est");}
if(direction<=338 && direction>292){lcd_aff_chaine("Sud / Est");}
}
}
///// FONCTIONS DE REGLAGE /////
///// fonctions TRANSFERT activé / désactivé ////////////////////// VOIR SI ON L'ENLEVE /////////////////
void trans_on_off (void)
{
lcd_efface();lcd_aff_chaine("transfert on : +");lcd_write_inst(0xC0);lcd_aff_chaine("transfert off: -");
while(ret==0){if(retour==0){ret=1;}if(plus==0){transfert=1;ret=1;}if(moins==0){transfert=0;ret=1;}}
tempo(2);
}
///// fonctions unité de la DIRECTION du vent/////
void unit_direction (void)
{
lcd_efface();lcd_aff_chaine("degres : +");lcd_write_inst(0xC0);lcd_aff_chaine("Pt cardinaux: -");
while(ret==0){if(retour==0){ret=1;}if(plus==0){unitdir=1;ret=1;}if(moins==0){unitdir=0;ret=1;}}
tempo(2);
}
///// fonctions unité de la VITESSE du vent /////
void unit_vitesse (void)
{
lcd_efface();lcd_aff_chaine("En Noeuds : +");lcd_write_inst(0xC0);lcd_aff_chaine("En km/h : -");
while(ret==0){if(retour==0){ret=1;}if(plus==0){unitvitesse=1;ret=1;}if(moins==0){unitvitesse=0;ret=1;}}
tempo(2);
}
///// FONCTION REGLAGE DE L'HEURE /////
void regl_heure (void)
{
lcd_efface();lcd_aff_chaine("Reglage heure :");tempo(2); // réglage des heures //
while(ret==0)
{
if(retour==0){ret=1;}lcd_ligne2();
if(plus==0)heu=heu+1;__delay_ms(100);if(heu>23)heu=0;lcd_aff_char(heu);
if(valid==0) //Appui sur touche valider pour confimer réglage heures et passer au minutes//
{
while(ret==0)
{
lcd_ligne1();lcd_aff_chaine("Reglage minutes :");lcd_ligne2();
if(retour==0){ret=1;}
if(plus==0)min=min+1;__delay_ms(100);if(min>59)min=0;lcd_aff_char(min);
if(valid==0)
{
while(ret==0)
{
lcd_ligne1();lcd_aff_chaine("Reglage secondes :");lcd_ligne2();
if(retour==0){ret=1;}
if(plus==0)sec=sec+1;__delay_ms(100);if(sec>59)sec=0;lcd_aff_char(sec);
if(valid==0)
{
while(ret==0)
{
lcd_ligne1();lcd_aff_chaine("Affichage heure :");lcd_ligne2();affiche_heure();
if(retour==0){ret=1;}
if(valid==0){ret=1;}
}
}
}
}
}
}
}
}
///// FONCTION TEST TRANSFERT ////////////////// VOIR SI ON L'ENLEVE /////
void test_transfert (void)
{
lcd_efface();
if (sec==60){min=min+1;sec=0;}
tempo(2);
}
///// FONCTIONS DES ALARMES /////////////////// VOIR SI ON L'ENLEVE /////
///// Alarme température /////
void alarme_temp (void)
{
lcd_efface();lcd_aff_chaine("Reglage Temperature :");tempo(2);
while(ret==0)
{
if(retour==0){ret=1;}
while(t==0)
{
lcd_efface();lcd_aff_chaine("Temp max : ");lcd_aff_char(altempmax);
if(plus==0){altempmax = altempmax++;if(altempmax==51)altempmax=0;}
if(moins==0){altempmax = altempmax--;if(altempmax==255)altempmax=50;}
if(valid==0){t=1;while(valid==0);}__delay_ms(100);__delay_ms(100);
}
while(t==1)
{
lcd_efface();lcd_aff_chaine("Temp Min : ");lcd_aff_char(altempmin);
if(plus==0){altempmin = altempmin++;if(altempmin==altempmax)altempmin=0;}
if(moins==0){altempmin = altempmin--;if(altempmin==255)altempmin=altempmax-1;}
if(valid==0){ret=1;t=2;while(valid==0);}__delay_ms(100);__delay_ms(100);
}
}
}
////// Alarme vitesse /////
void alarme_vitesse (void)
{
lcd_efface();lcd_aff_chaine("Reglage Vitesse :");tempo(2);
while(ret==0)
{
if(retour==0){ret=1;} //test touche retour
while(t==0)
{
lcd_efface();lcd_aff_chaine("Vitesse max: ");lcd_aff_char(alvitmax);
if(plus==0){alvitmax = alvitmax++;if(alvitmax==200)alvitmax=0;}
if(moins==0){alvitmax = alvitmax--;if(alvitmax==255)alvitmax=200;}
if(valid==0){t=1;while(valid==0);}__delay_ms(100);__delay_ms(100);
}
}
}
void delay_spe(int delai1) // Plusieurs tempos d'une centième de seconde interrompable avec la touche retour
{
i=0;while ((i<delai1)&&(retour!=0)){__delay_ms(1);i++;if (fonction==5){lcd_write_inst(0x80);affiche_heure ();}} //
}
void Tx(unsigned char Temp) // Fonction faisant le transfert en liaison série des caractères qu'il reçoit
{
while (PIR1bits.TXIF==0); // Attend que le registre TXREG soit vide
TXREG = Temp;
}
void transferer(void) // Fonction terminant les trames, et qui lance l'envoi de ces dernières vers l'écran 4D
{
temperaturefloat=(50*temperaturebrut)/255; // Calcul de la température en degrés Celsius
CRC = 13 ^ temperaturefloat; // Calcul du CRC (voir partie de l'écran 4D)
chaine_transfert[4]=temperaturefloat; // Ajout de la mesure à la trame
chaine_transfert[5]=CRC; // Ajout du CRC à la trame
directionfloat=(directionbrut*360)/256; // Calcul de la direction du vent en degrés
CRC = 10 ^ 20; // Calcul du CRC (voir partie de l'écran 4D)
chaine_transfert[10]=20; // Ajout de la mesure à la trame
chaine_transfert[11]=CRC; // Ajout du CRC à la trame
vitesse=VARbrut*314*36/10000;vitessefloat=(float)vitesse; // Calcul de la vitesse du vent en km/h
CRC = 20 ^ 120; // Calcul du CRC (voir partie de l'écran 4D)
chaine_transfert[16]=120; // Ajout de la mesure à la trame
chaine_transfert[17]=CRC; // Ajout du CRC à la trame
TXREG=(chaine_transfert[0]);TXIE=1; // Envoi du premier caractère de la trame
}
/* Programmes d'interruptions */
void interrupt high_priority nom_prg_it (void) //Interruption toutes les secondes pour le temps et pour faire les acquisitions, de plus toutes les 10 secondes, on envoit des trames pour l'écran 4D
{
if(TMR1IF)
{
/*PIR1bits.TMR1IF = 0; // Remise à '0' du flag timer 1
while ((TMR1L&0x01)!=0); // Attente d'une transistion pour changer la valeur du compteur
while ((TMR1L&0x01)==0);TMR1H = 0x80;*/
while(TMR1L&0x01==0);while(TMR1L&0x01==1);TMR1H = 0x80; // Préchargement pour débordement après 1s
sec++;sectempo++; // Incrémentation des secondes et du compteur de secondes pour la liaison série
if(sec>=60){sec=0;min++;}if(min>=60){min=0;heu++;}if(heu>=60){heu=0;}
acquisition_temperature();acquisition_vitesse_vent();acquisition_direction_vent();
if(sectempo>=10){sectempo=0;transferer();}
TMR1IF=0;
}
return;
}
void interrupt low_priority trans (void) // Interruption a chaque envoi par liaison série qui envoi le caractère suivant de la trame ou qui met fin au transfert
{
if(TXIF)
{
if(j!=24){j=j+1;Tx(chaine_transfert[j]);} // Vérifie que nous ne sommes pas au dernier caractère de la trame et envoie le caractère suivant
else{TXIE=0;j=0;} // Met fin au transfert caractère car la trame est terminée, elle est constituée de 24 caractères
}
return;
}