/********************************************************** Projet : tp_5s_master.prj Fichier(s) : TP_5s_master.c Objet : Voltmetre a affichage deporte MAITRE Auteurs : Hensinger Benoît / Cuenot Gaël Binome : 3 Groupe : RLI 1 Date création : **********************************************************/ // Fichiers à inclure : #include // Commandes du moniteur de mise au point #include // déclaration des registres interne au µC 80C535(SFR) #include // Commandes de l'afficheur LCD #include // Equivalences : #define OFF 0 #define ON 1 // Fonctions externes : // Fonctions locales (Prototypes) : void send_char_uart(char val); // Sous programme d'envoi d'un caractere sur la liaison serie void tempo_hard(unsigned int t); // Sous programme creant une base de temps materielle de 1 ms void it_P10_MESURE(void) interrupt 10 using 1; // Sous programme d'interruption de P1.0 void it_P11_ENVOI(void) interrupt 11 using 1; // Sous programme d'interruption de P1.1 void it_uart(void) interrupt 4 using 1; // Sous programme d'interruption de l'UART void it_T2(void) interrupt 5 using 1; // Sous programme d'interruption de T2 void it_CAN(void) interrupt 8 using 1; // Sous programme d'interruption du CAN // Definitions particulières (zone SFR ou RAM externe) : at 0xCC sfr16 THL2; at 0xCA sfr16 CRCHL; // Variables Globales : bit ok_trans,send_ready,reception; unsigned char tab_mesure[5]={0xFF,'0','0','0',0}; unsigned int val_ddp,i,j; char ans; // ================ ZONE PROGRAMME ============================== /******************************************************** Nom : main() Objet : initialisations, envoi des donnees et gestion des messages d'info Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void main () { clrscr(); // Efface l'ecran LCD printf("TP5S MAITRE \n"); // 1ere ligne LCD printf("\n\n---> ARRET <---"); // 2e ligne LCD // Parametres du CAN ADM=0; //Can en mode monocoup IADC=0; //Reset flag CAN //Choix du canal P6.2 MX2=0; MX1=1; MX0=0; EADC=0; //Inhibition des Interruptions du CAN //Init de l'UART SM0=0; //Mode 1,8 bits de données,bdrate variable SM1=1; SM2=1; BD=1; //Generateur de bdrate interne PCON=PCON|0x80; //Reglage SMOD : vitesse 9600 bauds (fq=12Mhz) REN=1; //Autorisation IRQ en reception RI=0; //Reset flag reception TI=0; //Reset flag emission ES=1; //Autorisation IRQ individuelle UART // Parametres de P1.0 I3FR=0; // Front montant sur P1.0 (marche) IEX3=0; // Reset drapeau EX3=1; // Autorisation IRQ sur P1.0 IEX4=0; // Reset drapeau EX4=0; // Inhibition IRQ P1.1 // Initialisation du Timer T2 CRCHL=-1000/1; // Periode T2 = 1 ms THL2=CRCHL; // Initialisation de T2 T2PS=0; // Ftimer = Fq/12 T2R0=0; // Mode 0 auto-reload T2R1=1; T2I0=1; // Mode timer T2I1=0; TF2=0; // Reset du flag de T2 ET2=1; // Autoriasation IRQ de T2 //Def des priorites (3 pour l'UART, 1 pour P1.0, P1.1, T2 et 0 pour le CAN) IP0=(IP0 & 0xC2) | 0x3C; IP1=(IP1 & 0xC2) | 0x10; EAL=1; //Autorisation globale des IRQ val_ddp=0; // On met a 0 val_ddp pour commencer ok_trans=1; // Pour que l'UART puisse emettre // Preparation a l'envoi de la trame de test j=0; // Variable utilisee pour envoyer plusieurs fois la meme trame send_ready=1; // Autoriser l'envoi de la trame tab_mesure[4]=~((tab_mesure[0]+tab_mesure[1]+tab_mesure[2]+tab_mesure[3])%8); // Calcul du checksum de la trame de test while(1) // Boucle infinie { while(send_ready==1) // Tant qu'on veut envoyer une trame { send_ready=0; // Reset de la variable do { for(i=0;i<5;i++) // Envoi de la trame (5 octets) send_char_uart(tab_mesure[i]); if(reception==1) // Si on recoit quelque chose { reception=0; // Reset de la variable if(ans=='!') printf("\n\nOK transmition "); // Si on a recu un ! c'est que tout est ok else printf("\n\nPB transmition "); // Si on a recu un ? c'est qu'il y a un pb de transmission j=6; // Pour sortir de la do while } else { tempo_hard(500); // Tempo de 500 milisecondes j++; if(j==5) // Si l'esclave n'a pa repondu apres 5 envoi de la meme trame c'est qu'il n'est pas connecte printf("\n\n!Cible absente!"); } } while(j<=5); // Envoi de la trame 5 fois de suite } } } // end main /******************************************************** Nom : can Objet : realise la conversion analogique/numerique de la mesure Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void it_CAN(void) interrupt 8 using 1 { val_ddp=ADDAT; //recuperation valeur conversion CAN val_ddp=val_ddp*196/100+1; //Affichage en dizaine de mV IADC=0; //reset flag } //Retour /******************************************************** Nom : ip_P10_MESURE Objet : Mesure de la tension Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void it_P10_MESURE(void) interrupt 10 using 1 { printf("\n\n MESURE EN COURS"); // 2e ligne LCD IEX3=0; //Reset flag P1.0 EADC=1; //autorise IRQ CAN DAPR=0; // demarrage conversion EX4=1; //Autorisation P1.1 pour envoi } // End ip_P10_MESURE /******************************************************** Nom : ip_P11_ENVOI Objet : Autorise l'envoi des donnees et converti les valeurs mesurees en caracteres ASCII Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void it_P11_ENVOI(void) interrupt 11 using 1 { printf("\n\n %u ",val_ddp); // 2e ligne LCD IEX4=0; // Reset du flag de P1.1 EADC=1; // Autorisation IRQ du CAN tab_mesure[1]=(val_ddp/100)+0x30; // On stock dans le tableau la valeur ASCII de la partie entiere de la mesure tab_mesure[2]=((val_ddp-(val_ddp/100*100))/10)+0x30; // On stock dans le tableau la valeur ASCII des dixiemes de volt tab_mesure[3]=(val_ddp-(val_ddp/10*10))+0x30; // On stock dans le tableau la valeur ASCII des centiemes de volts tab_mesure[4]=~((tab_mesure[0]+tab_mesure[1]+tab_mesure[2]+tab_mesure[3])%8); // Calcul du checksum send_ready=1; // Autoriser l'envoi de la trame j=0; } // End ip_P11_ENVOI /******************************************************** Nom : it_T2 Objet : Sous programme d'interruption de T2 Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void it_T2(void) interrupt 5 using 1 { TF2=0; // Reset du flag de T2 cpt++; } // End it_T2 /******************************************************** Nom : it_uart Objet : gestion de l'interruption de l'uart Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void it_uart(void) interrupt 4 using 1 { char val; if(RI==1) // Si on est en reception { RI=0; // Reset du flag val=SBUF; // On stock les donnees recues dans val if(val=='!' || val=='?') // Si on a recu un des caracteres souhaites ... { ans=val; reception=1; // On a recu quelque chose de coherent } else printf("\n\nPb de reception"); // 2e ligne LCD } else { TI=0; // Reset du flag ok_trans=1; // Autorise le transfert d'1 caractere } } // End it_uart /******************************************************** Nom : send_char_uart Objet : Envoye un caractere Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void send_char_uart(char val) { while(ok_trans==0) { } SBUF=val; ok_trans=0; } //Retour /******************************************************** Nom : tempo_hard Objet : base de temps materielle de 1 ms Paramètres : - d'appel : durée de la tempo en ms - de retour : aucun *********************************************************/ void tempo_hard(unsigned int t) { cpt=free_cpt+t; while(free_cpt != cpt); } // end tempo