Programme

/******************************************************************************
* 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;
}