/********************************************************** Projet : tp_2s.prj Fichier(s) : TP_2s.c Objet : Gestion d'un carrefour par interruptions Auteurs : Hensinger Benoît / Cuenot Gaël 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 tempo(unsigned int); // Fonction temporisation (delai) void mode_off(void); // Fonction mode OFF void mode_jour(void); // Fonction mode JOUR void mode_nuit(void); // Fonction mode NUIT void mode_clign(void); // Fonction mode CLIGNOTANT void erreur(void); // Fonction d'erreur au cas ou aucun mode valide ne serai selectionne void IRQ_P10(void) interrupt 10 using 1; // Fonction d'interruption sur P1.0 (selection du mode) void IRQ_P11(void) interrupt 11 using 1; // Fonction d'interruption sur P1.1 (appel voitures) void IRQ_P14(void) interrupt 9 using 1; // Fonction d'interruption sur P1.4 (appel pieton) // Definitions particulières (zone SFR ou RAM externe) : // Variables Globales : code unsigned char Tab_voit[6]={0x21,0x22,0x24,0x0C,0x14,0x24}; // Tableau de valeurs des feux des voies principale et secondaire code unsigned char Tab_piet[6]={0x09,0x05,0x05,0x06,0x06,0x05}; // Tableau de valeurs des feux pietons code unsigned int Tab_tmp[6]={10000,1000,1000,5000,1000,1000}; // Tableau de valeurs des tempo code unsigned char Tab_mode[4]={0x80,0x10,0x20,0x40}; // Tableau de valeurs des feux de selection de mode int mode=0; int state=0; bit appel=0; // ================ ZONE PROGRAMME ============================== /******************************************************** Nom : main() Objet : Gestion d'un carrefour par interruptions Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void main () { clrscr(); printf(" --> TP 2 S <-- \n"); // 1ere ligne LCD P4=0; // Reset de P4 P5=0; // Reset de P5 //Interruption sur P1.0 I3FR=1; // Front Montant sur P1.0 (selection du mode) IEX3=0; // Reset flag EX3=1; // Autorisation IRQ //Interruption sur P1.1 IEX4=0; // Reset flag EX4=1; // Autorisation IRQ //Interruption sur P1.4 I2FR=1; // Front descendant sur P1.4 IEX2=0; // Reset flag EX2=1; // Autorisation IRQ IP0=(IP0 & 0xFD) | 0x04; // Priorites des IRQ IP1=(IP1 & 0xFD) | 0x02; EAL=1; // Autorisation globale while(1) // Boucle infinie { P5=(P5 & 0x0F) | Tab_mode[mode]; // Affichage du mode (leds jour, nuit, clign et off) switch(mode) { case 0: // Mode OFF (tout le carrefour eteint) mode_off(); break; case 1: // Mode JOUR (fonctionnement normal du carrefour) mode_jour(); break; case 2: // Mode NUIT (voie principale au vert, mode_nuit(); // voie secondaire au rouge) break; case 3: // Mode CLIGNOTANT (tous les feux clignotent a l'orange, mode_clign(); //les feux pietons au rouge) break; default: // Si aucun mode correct n'est selectionne erreur(); break; } } } // end main /******************************************************** Nom : selection Objet : Selection du mode Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void IRQ_P10(void) interrupt 10 using 1 { tempo(100); // Anti rebonds logiciel IEX3=0; // Reset flag if(mode<3) mode++; else mode=0; IEX3=0; // Reset flag } /******************************************************** Nom : Appel Voiture Objet : Effectue 1 cycle du mode jour a la suite d'un appel voiture. Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void IRQ_P11(void) interrupt 11 using 1 { tempo(100); // Anti rebond logiciel IEX4=0; // Reset flag if(mode == 2) // Si on est en mode nuit { if(state == 0) { appel=1; // Variable permettant de signaler l'appel printf("\n\n!APPEL VOITURE!"); // 2e ligne LCD tempo(1000); // Tempo permettant de voir le message sur le LCD mode_jour(); } } IEX4=0; // Reset flag } /******************************************************** Nom : Appel Pieton Objet : Effectue 1 cycle du mode jour a la suite d'un appel pieton. Paramètres : - d'appel : aucun - de retour : aucun *********************************************************/ void IRQ_P14(void) interrupt 9 using 1 { tempo(100); // Anti rebond logiciel IEX2=0; // Reset flag if(mode == 2 && state == 0) { appel=1; // Variable permettant de signaler l'appel printf("\n\n! APPEL PIETON !"); // 2e ligne LCD tempo(1000); // Tempo permettant de voir le message sur le LCD mode_jour(); } IEX2=0; // Reset flag } /************************************************************************************* Nom : mode_off Objet : fonctionnement du carrefour en mode OFF. Paramètres : - d'appel : aucun - de retour : aucun **************************************************************************************/ void mode_off(void) { printf("\n\n>> Mode: OFF << "); // 2e ligne LCD P4=0; // Extinction de P4 en entier P5=(P5 & 0xF0) | 0x00; // Extinction des leds de P5 sauf celles des modes } // end mode_off /************************************************************************************* Nom : mode_jour Objet : fonctionnement du carrefour en mode JOUR. Paramètres : - d'appel : aucun - de retour : aucun **************************************************************************************/ void mode_jour(void) { if(appel != 1) // Test si il y a un appel voiture ou pieton printf("\n\n>> Mode: JOUR <<"); // 2e ligne LCD en cycle normal else printf("\n\n>>Mode: NUIT A<<"); // 2e ligne LCD en cas d'appel pieton ou voiture P4=(P4 & 0xC0) | Tab_voit[state]; // Affichage des leds des voies P5=(P5 & 0xF0) | Tab_piet[state]; // Affichage des leds pour les pietons tempo(Tab_tmp[state]); // Tempo correspondante state++; if(state > 5) state=0; if(appel == 1 && state > 5) // Si on etait dans le cas d'1 appel on retourne en mode nuit mode_nuit(); } // end mode_jour /************************************************************************************* Nom : mode_nuit Objet : fonctionnement du carrefour en mode NUIT. Paramètres : - d'appel : aucun - de retour : aucun **************************************************************************************/ void mode_nuit(void) { if(state == 0) { printf("\n\n>> Mode: NUIT <<"); // 2e ligne LCD P4=(P4 & 0xC0) | Tab_voit[0]; // Affichage des leds des voies P5=(P5 & 0xF0) | Tab_piet[0]; // Affichage des leds des pietons } else { mode_jour(); } } // end mode_nuit /************************************************************************************* Nom : mode_clign Objet : fonctionnement du carrefour en mode CLIGNOTANT. Paramètres : - d'appel : aucun - de retour : aucun **************************************************************************************/ void mode_clign(void) { printf("\n\nMode: CLIGNOTANT"); // 2e ligne LCD P4=0x12; // Tous les feux de voies au orange P5=(P5 & 0xF0) | 0x05; // Les autres sont eteints sauf les leds de mode tempo(500); // tempo pour le clignotement P4=0; // Extinction de toutes les leds pour le clignotement tempo(500); } // end mode_clign /************************************************************************************* Nom : erreur Objet : Signale qu'aucun mode de fonctionnement valide n'est selectionne et fait fonctionner le carrefour en mode clignotant. Paramètres : - d'appel : aucun - de retour : aucun **************************************************************************************/ void erreur(void) { printf("\n\n !!! ERREUR !!! "); // 2e ligne LCD mode_clign(); } // end erreur /******************************************************** Nom : tempo Objet : base de temps logicielle de 1 ms Paramètres : - d'appel : durée de la tempo en ms - de retour : aucun *********************************************************/ void tempo(unsigned int t) { int ttempo; while (t != 0) { for (ttempo = 1;ttempo < 493;ttempo++); t--; // décrémentation de la variable de contrôle } } // end tempo