Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
fr:supervisors:solutions:didalab:exercice1 [2010/05/27 20:06] – créée sdeniaudfr:supervisors:solutions:didalab:exercice1 [2020/07/20 09:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Exercice 1 (TP4) ====== ====== Exercice 1 (TP4) ======
 +
 +===== Organigrammes =====
 +
 +
 +==== Fonction principale ====
 +
 +{{:fr:supervisors:solutions:didalab:ex1_tp4_organigramme1.png?600|}}
 +
 +
 +==== Fonction d'interruption ====
 +
 +{{:fr:supervisors:solutions:didalab:ex1_tp4_organigramme2.png|}}
 +
 +
 +===== Programme =====
 +
 +<code c>
 +
 +/************************************************************************************************
 + *       TPs sur  EID210 / Réseau CAN - VMD  (Véhicule Multiplexé Didactique) 
 + *************************************************************************************************
 + *       APPLICATION: Commande Essuie-glace
 + *************************************************************************************************
 + *  TP Exercice  n°1:  Séquence commande moteur E.G.
 + *------------------------------------------------------------------------------------------------
 + *   CAHIER DES CHARGES :      
 + *  *********************      
 + *   On souhaite que l'état du moteur dépende de la position du commodo
 + *  - Si Position 1 Moteur en marche à faible vitesse 
 + * - Si Position 2 Moteur en marche à grande vitesse 
 + * - Si Position 3 Moteur en marche à vitesse ajustable par l'entrée analogique
 + * - Si Position 4 Moteur en marche périodique avec dans l'état marche une vitesse ajustable
 +  *----------------------------------------------------------------------------------------------
 + *  NOM du FICHIER :  TP_Exercice 1.C        
 + * *****************
 + *************************************************************************************************/
 +// Fichiers à inclure
 +//********************
 +#include <stdio.h>
 +#include "Structures_Donnees.h"
 +#include "cpu_reg.h"
 +#include "eid210_reg.h"
 +#include "Can_vmd.h"
 +#include "Aton_can.h"
 +
 +// Variables globales
 +//---------------------
 +union byte_bits Indicateurs;
 +#define I_Affiche Indicateurs.bit.b0
 +#define I_Fin_Tempo Indicateurs.bit.b1
 +#define I_Active_Tempo Indicateurs.bit.b2
 +#define I_Etat_Moteur Indicateurs.bit.b3
 +unsigned int Compteur_Passage_Irq;
 +
 +//  Fonction d'interruption "Base de Temps"
 +//========================================
 +void irq_bt()
 +// Fonction exécutée toute les 10 mS
 +{if(I_Active_Tempo) // Si mode intermittent actif
 + {Compteur_Passage_Irq++;
 + if(Compteur_Passage_Irq==400)  // 4  Secondes se sont écoulées
 + {Compteur_Passage_Irq=0;
 + I_Fin_Tempo=1;
 + }
 + }
 +} // Fin de la fonction d'interruption
 +
 +//==========================
 +//  FONCTION PRINCIPALE
 +//==========================
 +main()
 +{// Définition de variables locales
 +int Compteur_Passage;
 +unsigned char Commodo_EG_Mem;
 +unsigned int Cptr_TimeOut;
 +unsigned char AN0H; // Pour mémoriser les 8 biits de poids forts du résultat de conversion A->N
 +unsigned char Val_Vitesse,Val_Vitesse_Mem;
 +
 +Trame Trame_Recue; 
 +Trame T_IRM_Commodo_EG; // Trame pour interroger Module 8E sur Commodo Essuie Glace  
 + // IRM -> Information Request Message -> Trame interrogative
 +Trame T_IM_Commodo_EG; // Trame pour commander le Module 8E sur Commodo Essuie Glace  
 + // IM -> Information Message -> Trame de commande
 +Trame T_IM_Asservissement; // Trame pour commander le module "Asservissement" 
 + // IM -> Information Message -> Trame de commande
 +// Initialisations
 +//*****************
 +
 +/* Initialisation DU SJA1000 de la carte PC104 */
 +Init_Aton_CAN();
 +// Pour initialiser les liaisons en entrées  noeud "Commodo_EG"
 +T_IM_Commodo_EG.trame_info.registre=0x00;
 +T_IM_Commodo_EG.trame_info.champ.extend=1; // On travaille en mode étendu
 +T_IM_Commodo_EG.trame_info.champ.dlc=0x03; // Il y aura 3 données de 8 bits (3 octets envoyés)
 +T_IM_Commodo_EG.ident.extend.identificateur.ident=Ident_T_IM_Commodo_EG;
 +T_IM_Commodo_EG.data[0]=0x1F; // première donnée -> "Adresse" du registre concernée 
 + //(GPDDR donne la direction des I/O) adresse = 1Fh  page 16
 +T_IM_Commodo_EG.data[1]=0x7F; // deuxième donnée -> "Masque" 
 +   //-> Tous les bits concernés sauf GP0 (voir doc page 16)
 +T_IM_Commodo_EG.data[2]=0x7F; // troisième donnée -> "Valeur" -> Tous les bits en entrée
 +// Envoi trame pour définir de la direction des entrées sorties
 +Ecrire_Trame(T_IM_Commodo_EG);  // Envoyer trame sur réseau CAN
 + Cptr_TimeOut=0;
 + do{Cptr_TimeOut++;}while((Lire_Trame(&Trame_Recue)==0)&&(Cptr_TimeOut<2000));
 + if(Cptr_TimeOut==2000)
 + { clsscr();
 +   gotoxy(2,12);
 +   printf(" Pas de reponse a la trame de commande en initialisation \n");
 +   printf(" Couper et/ou  remettre    alimentation 12 V  \n");
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // On attend les trames  "On Bus"
 +              for(Cptr_TimeOut=0;Cptr_TimeOut<200000;Cptr_TimeOut++);
 +              Ecrire_Trame(T_IM_Commodo_EG);  // Renvoyer trame IM sur réseau CAN
 +   Cptr_TimeOut=0;
 +   do{Cptr_TimeOut++;}while((Lire_Trame(&Trame_Recue)==0)&&(Cptr_TimeOut<2000));
 +   if(Cptr_TimeOut==2000)
 + { gotoxy(2,12);
 +     printf(" Pas de reponse a la trame de commande en initialisation \n");
 +   printf("  Modifier le programme et recommencer  \n");
 +         do{}while(1); // On reste bloqué, on ne continue pas
 +
 + }
 +// Pour activer les conversions Ana -> Num
 +T_IM_Commodo_EG.data[0]=0x2A; // Adresse du registre ADCON0  
 +T_IM_Commodo_EG.data[1]=0xF0; // Masque -> bits 7..4 concernés
 +T_IM_Commodo_EG.data[2]=0x80; // Valeur ->  ADON=1 et "prescaler rate"=1:32
 +Ecrire_Trame(T_IM_Commodo_EG);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour définir le mode de conversion
 +T_IM_Commodo_EG.data[0]=0x2B; // Adresse du registre ADCON1  
 +T_IM_Commodo_EG.data[1]=0xFF; // Masque -> tous les bits sont concernés
 +T_IM_Commodo_EG.data[2]=0x0C; // Valeur ->  voir doc MCP25050 page 36
 +Ecrire_Trame(T_IM_Commodo_EG);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour initialiser le module "Asservissement"
 +// Trame de type "IM" (trame de commande): Données d'identification pour le noeud "Asservissement"
 +T_IM_Asservissement.trame_info.registre=0x00;
 +T_IM_Asservissement.trame_info.champ.extend=1;
 +T_IM_Asservissement.trame_info.champ.dlc=0x03;
 +T_IM_Asservissement.trame_info.champ.rtr=0;
 +T_IM_Asservissement.ident.extend.identificateur.ident=Ident_T_IM_Asservissement;
 +// Pour définir des Entrées/Sorties
 +T_IM_Asservissement.data[0]=0x1F; // Adresse du registre GPDDR  (direction de E/S)
 +T_IM_Asservissement.data[1]=0xEF; // Masque -> Bit 7 non concerné 
 +T_IM_Asservissement.data[2]=0xE3; // Valeur ->  1 si Entrée et 0 si Sortie
 + // GP7=fs Entrée; GP6=fcg Entree; GP5=fcd Entrée;  GP4=ValidIP Sortie; 
 + // GP3=PWM2 Sortie; GP2=PWM1 Sortie; GP1=AN1 Entrée; GP0=AN0 Entrée; 
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre trame réponse (acquitement)
 +// Pour mettre à 0 les sorties 
 +T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +T_IM_Asservissement.data[1]=0x1C; // Masque -> sorties GP4,3,2 sont consernées
 +T_IM_Asservissement.data[2]=0x00; // Valeur ->  les 3 sorties sont forcée à 0  (ValidIP=0)
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse (acquitement)
 +// Pour définir sortie GP2 en PWM1  
 +T_IM_Asservissement.data[0]=0x21; // Adresse du registre T1CON
 +T_IM_Asservissement.data[1]=0xB3; // Masque -> seuls bit 7;5;4;1;0 consernés
 +T_IM_Asservissement.data[2]=0x80; // Valeur ->  TMR1ON=1; Prescaler1=1
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse (acquitement)
 +// Pour définir fréquence signal sortie PWM1  
 +T_IM_Asservissement.data[0]=0x23; // Adresse du registre PR1
 +T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +T_IM_Asservissement.data[2]=0xFF; // Valeur ->  PR1=255
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse (acquitement)
 +
 +// Pour trame interrogative envoyée au commodo Essuie-Glace  -> 'IRM'   (Information Request Message)
 +// Définir données d'identification
 +T_IRM_Commodo_EG.trame_info.registre=0x00;
 +T_IRM_Commodo_EG.trame_info.champ.extend=1;
 +T_IRM_Commodo_EG.trame_info.champ.dlc=0x08;   // On attend 8 octets en réponse
 +T_IRM_Commodo_EG.trame_info.champ.rtr=1;
 +T_IRM_Commodo_EG.ident.extend.identificateur.ident=Ident_T_IRM8_Commodo_EG;
 + // Voir définitions dans fichier CAN_VMD.h
 +// Une première acquisition pour initialiser les grandeurs mise en mémoire
 +Ecrire_Trame(T_IRM_Commodo_EG); // On envoi une première trame interrogative pour initialiser la mémoire
 +do{}while(Lire_Trame(&Trame_Recue)==0);
 +Commodo_EG.valeur=Trame_Recue.data[1]&0xF0;
 +Commodo_EG_Mem=Commodo_EG.valeur;  // On met en mémoire l'état actuel pour comparaison ultéérieure
 +Val_Vitesse=Trame_Recue.data[2]; // On récupére les MSB de la conversion A-> voie AN0 
 +Val_Vitesse_Mem=Val_Vitesse;  // On met en mémoire la valeur pour comparaison ultérieure
 +// Pour les indicateurs binaires
 +Indicateurs.valeur=0; //Tous les indicateurs sont positionnés à 0
 +
 +// Les initialisations se sont bien passée
 +// On peut afficher le titre du TP
 +clsscr();
 +gotoxy(1,2);
 +printf("    *************************************************************\n");
 +printf("      TPs sur Reseau CAN    Application: Commande Essui-glace    \n");
 +printf("     ------------------------------------------------------------\n");
 +printf("      TP exercie n°1        Sequence de commande  moteur E.G.    \n");
 +printf("      La vitesse moteur depend de la position commodo            \n");
 +printf("           Pos1: Petite vitesse       Pos2: Grande Vitesse       \n");
 +printf("        Pos3: Vitesse Ajustable  Pos4: Fonctionnement périodique \n");
 +printf("    **************************************************************\n");
 +
 +// Pour initialiser la base de temps et temporisations
 +SetVect(96,&irq_bt); // mise en place de l'autovecteur 
 +PITR = 0x0048; // Une interruption toutes les 10 millisecondes 
 +PICR = 0x0760; //  96 = 60H
 +
 +// Boucle principale
 +//*******************
 +   do
 + {  Ecrire_Trame(T_IRM_Commodo_EG); // On envoi trame interrogative au noeud commodo Essuie-Glace
 +         // On attend la réponse
 +    do{}while(Lire_Trame(&Trame_Recue)==0);  // La fonction renvoie 1 dans ce cas
 + if (Trame_Recue.ident.extend.identificateur.ident==Ident_T_IRM8_Commodo_EG)
 +
 + Commodo_EG.valeur=Trame_Recue.data[1]&0xF0; // On récupére les états des entrées binaires
 + if(Commodo_EG.valeur!=Commodo_EG_Mem)
 +    {// S'il y a eu changement d'une des entrées binaires, on commande le moteur
 + if(Commodo_EG.bit.GP4==0) // On test GP4 (BP1) du commodo EG
 +       { // BP1 est actionné  (GP4=0)
 +   I_Active_Tempo=0;
 +      gotoxy(2,12);
 +         printf("   Action sur BP1 (GP4)  \n" );  
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x10; // ValidIP =1 donc moteur en marche
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +        // Pour modifier le rapport cyclique PWM1 -> c'est le module de la commande    
 +       T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC
 +       T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +       T_IM_Asservissement.data[2]=40; // Valeur ->PWM1DC   Vitesse lente
 +       Ecrire_Trame(T_IM_Asservissement);  // Le moteur ne peut tourner car ValidIP=0
 +       do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 +      //else {
 + if(Commodo_EG.bit.GP5==0) // On test GP5 (BP2) du commodo EG
 +        { // BP2 est actionné  (GP5=0)
 +   I_Active_Tempo=0;
 +      gotoxy(2,12);
 +         printf("   Action sur BP2 (GP5) \n" );  
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x10; // ValidIP =1 donc moteur en marche
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +        // Pour modifier le rapport cyclique PWM1 -> c'est le module de la commande    
 +       T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC
 +       T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +       T_IM_Asservissement.data[2]=70; // Valeur ->PWM1DC   Vitesse rapide
 +       Ecrire_Trame(T_IM_Asservissement);  // Le moteur ne peut tourner car ValidIP=0
 +       do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 + //else {
 + if(Commodo_EG.bit.GP6==0) // On test GP6 (BP3) du commodo EG
 +        { // BP3 est actionné  (GP6=0)
 +   I_Active_Tempo=0;
 +      gotoxy(2,12);
 +         printf("   Action sur BP3 (GP6)\n" );  
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x10; // ValidIP =1 donc moteur en marche
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +        // Pour modifier le rapport cyclique PWM1 -> c'est le module de la commande    
 +       T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC
 +       T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +       T_IM_Asservissement.data[2]=Val_Vitesse; // Valeur ->PWM1DC   Vitesse réglable
 +       Ecrire_Trame(T_IM_Asservissement);  // Le moteur ne peut tourner car ValidIP=0
 +       do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 +       //else {
 + if(Commodo_EG.bit.GP7==0) // On test GP6 (BP3) du commodo EG
 +        { // BP3 est actionné  (GP6=0)
 +   I_Active_Tempo=1;
 +      gotoxy(2,12);
 +         printf("   action sur BP4 (GP7)\n" );  
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x10; // ValidIP =1 donc moteur en marche
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +        // Pour modifier le rapport cyclique PWM1 -> c'est le module de la commande    
 +       T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC
 +       T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +       T_IM_Asservissement.data[2]=Val_Vitesse; // Valeur ->PWM1DC   Vitesse réglable
 +       Ecrire_Trame(T_IM_Asservissement);  // Le moteur ne peut tourner car ValidIP=0
 +       do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 +  //else  {
 + // ni BP1 ni BP2 ni BP3 ni BP4 actionné  ->  On arrete donc le moteur
 + if(Commodo_EG.valeur==0xF0)
 + {I_Active_Tempo=0;
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x00; // ValidIP =0 donc moteur à l'arret
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +   gotoxy(2,12);
 +   printf("   Moteur a l'arret          \n");
 + }
 + gotoxy(2,14);
 +       printf("   Valeur entrees binaires = %2.2x \n",Commodo_EG.valeur);  // On affiche sa valeur
 +       }// Fin si changement d'une des entrées binaires
 + // Pour l'entrée analogique
 + Val_Vitesse=Trame_Recue.data[2]; // On récupére les MSB de la conversion A-> voie AN0 
 + if(Val_Vitesse!=Val_Vitesse_Mem) 
 +   {   gotoxy(2,16);
 +         printf("   Valeur entree analogique = %3d \n",Val_Vitesse);  // On affiche sa valeur
 + if((Commodo_EG.bit.GP6==0)||(Commodo_EG.bit.GP7==0))
 +        {// Pour modifier le rapport cyclique PWM1 -> c'est le module de la commande    
 +     T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC
 +     T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont consernés
 +     T_IM_Asservissement.data[2]=Val_Vitesse; // Valeur ->PWM1DC   
 +     Ecrire_Trame(T_IM_Asservissement);  // Le moteur ne peut tourner car ValidIP=0
 +     do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 +   }
 + // Mise en mémoire des valeurs acquises
 + Commodo_EG_Mem = Commodo_EG.valeur;  // On met en mémoire l'état des entrées binaires
 + Val_Vitesse_Mem=Val_Vitesse; // On met en mémoire le résultat de conversion A->N
 + } // Fin si identificateur correct
 + // Pour mode périodique
 + if(I_Active_Tempo==1)
 + {if(I_Fin_Tempo==1)
 + {I_Fin_Tempo=0;
 + if(I_Etat_Moteur==1)
 + {I_Etat_Moteur=0;
 +   T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x00; // ValidIP =0 donc moteur à l'arret
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 + else
 + {I_Etat_Moteur=1;
 +    T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +   T_IM_Asservissement.data[1]=0x10; // Masque -> seule la sortie ValidIP sera consernée
 +   T_IM_Asservissement.data[2]=0x10; // ValidIP =1 donc moteur en marche
 +   Ecrire_Trame(T_IM_Asservissement);  
 +   do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + }
 + }
 + }
 + }while(1);// FIN de la boucle principale
 +}// FIN fonction principale
 +
 +
 +
 +</code>
 +
 +
  
fr/supervisors/solutions/didalab/exercice1.1274990771.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0