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:exercice2 [2010/05/27 20:06] – créée sdeniaudfr:supervisors:solutions:didalab:exercice2 [2020/07/20 09:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Exercice 2 (TP5) ====== ====== Exercice 2 (TP5) ======
 +
 +===== Organigramme =====
 +
 +{{:fr:supervisors:solutions:didalab:ex2_tp5_organigramme1.png?600|}}
 +
 +===== Programme =====
 +
 +<code c>
 +
 + /************************************************************************************************
 + *       TPs sur  EID210 / Réseau CAN - VMD  (Véhicule Multiplexé Didactique)
 + *************************************************************************************************
 + *       APPLICATION: Commande Essuie-glace à distance
 + *************************************************************************************************
 + *   TP Exercice n°2:  Réguler la vitesse du moteur essuie-glace avec correcteur P
 + *----------------------------------------------------------------------------------------------- 
 +
 + *   CAHIER DES CHARGES :      
 + *  *********************      
 + *      Réguler la vitesse du moteur EG avec pour consigne, l'entrée analogique du commodo E.G.
 + * La commande du moteur se fait boucle fermé avec correcteur à action proportionnelle 
 + *      Commande = Kp*Ecart = Kp * (Consigne - Mesure)
 + *------------------------------------------------------------------------------------------------
 + *  NOM du FICHIER :  TP_Exercice 2.C        
 + * *****************
 + *************************************************************************************************/
 +
 +// Déclaration des fichiers d'inclusion
 +#include <stdio.h>
 +#include"Structures_Donnees.h"
 +#include"cpu_reg.h"
 +#include "eid210_reg.h"
 +#include "CAN_vmd.h"
 +#include "Aton_can.h"
 +
 +// Déclarations des diverses trames de communication
 +Trame Trame_Recue; // Pour la trame qui vient d'etre reçue par le controleur
 +// Trmes de type "IM" (Input Message -> trame de commande)
 +Trame T_IM_Asservissement; // Pour la commande du moteur
 +Trame T_IM_Commodo_EG;
 +Trame T_IRM_Commodo_EG; // Pour l'acquisition des entrées Commodo EG
 +// Déclaration des variables 
 +// Pour les Indicateurs divers (variables binaires)
 +union byte_bits Indicateurs; // Structures de bits
 +#define I_Sens_Rotation Indicateurs.bit.b0 
 +#define I_Attente_Reponse_IRM Indicateurs.bit.b1 
 +#define I_Message_Pb_Affiche Indicateurs.bit.b2 
 +// Pour les résultats de conversion
 +unsigned short S_Mesure_Vitesse,S_Consigne,S_Temp;
 +unsigned char AN0H,AN1H,AN10L;
 +// Pour régulateur de vitesse
 +int Ecart,Resultat_Calcul;
 +unsigned char Cde_Moteur;
 +// Déclaration constante pour régulation
 +#define Kp 6 // Coefficient d'action proportionnelle -> Ce doit etre un entier
 + //en fait valeur réelle Kp/16 = 6/16
 +
 +//======================
 +// FONCTION PRINCIPALE
 +//======================
 +main()
 +{
 +//  INITIALISATIONS
 +//------------------
 +// Déclaration de variables locales à la fonction principale
 +// Les différents compteurs
 +unsigned int Cptr_Affichage,Cptr_TimeOut,Ctpr_Acquisition;
 +// Initilisation carte controleur réseau CAN
 +Init_Aton_CAN();
 +// Effacer l'écran
 +clsscr();
 +// Pour initialiser les liaison en entrées du noeud "Commodo Essuie-Glace"
 +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; // Valeur ->  1 si Entrée et 0 si Sortie  (Toutes en entrées)
 +
 +// Pour envoyer trame et test si réponse  (avec Time Out
 +I_Message_Pb_Affiche=0;
 +do {Ecrire_Trame(T_IM_Commodo_EG); // C'est la première trame envoyée
 + Cptr_TimeOut=0; // On teste si le module répond bien
 + do{Cptr_TimeOut++;}while((Lire_Trame(&Trame_Recue)==0)&&(Cptr_TimeOut<500));
 + if(Cptr_TimeOut==500)
 + {if(I_Message_Pb_Affiche==0)
 + {I_Message_Pb_Affiche=1;
 +   gotoxy(2,10);
 +   printf(" Pas de reponse a la trame de commande en initialisation \n");
 + printf("  Verifier si alimentation 12 V  est OK   ...  PUIS    \n");
 + printf("  FAIRE un Reset de la carte processeur EID 210  ...  PUIS  \n");
 + printf("  RECHARGER le programme et RELANCER \n");
 + do{}while(1);}}
 +    }while(Cptr_TimeOut==500);
 +// La première tramme est bien passée ... on peut continuer!
 +clsscr();
 +// Pour afficher titre
 +gotoxy(1,2);
 +printf("    ********************************************************************  \n");
 +printf("     TPs sur Reseau CAN    Application: Commande Essui-Glace              \n");
 +printf("    --------------------------------------------------------------------  \n");
 +printf("     TP Exercice  n°2:     REGULER LA VITESSE DU MOTEUR Essuie-Glace      \n");
 +printf("    ********************************************************************  \n");
 +printf("      - en agissant sur l'entree analogique 0 sur module Commodo_EG      \n");
 +printf("      - en boucle fermee en mode proportionnel Sr = Kp(Consigne -Mesure) \n");
 +printf("    ******************************************************************** \n");
 +
 +
 +// 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
 +// Trame de type "IRM" (trame interrogative): Données d'identification du commodo EG
 +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 demande les valeurs de 8 rgistres
 +T_IRM_Commodo_EG.trame_info.champ.rtr=1;
 +T_IRM_Commodo_EG.ident.extend.identificateur.ident=Ident_T_IRM8_Commodo_EG; //
 + 
 +// Initialisation des différentes trames et envoi aux modules "Asservissement"
 +// Trame de type "IM" (trame de commande): Données d'identification
 +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)
 + // doc MCP25050 Page 16 
 +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 réponse
 +// 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 à 0
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// 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
 +// 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
 +// Pour Valider le circuit de puissance
 +T_IM_Asservissement.data[0]=0x1E; // Adresse du registre GPLAT  (Registre I/O)
 +T_IM_Asservissement.data[1]=0x10; // Masque -> sortie GP4 (ValidIP) est conserné
 +T_IM_Asservissement.data[2]=0x10; // Valeur ->  
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour initialiser le rapport cyclique  (valeur initiale)
 +T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC (Charger cde vitesse)
 +T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont concernés
 +T_IM_Asservissement.data[2]=0; // Valeur ->  Commande vitesse à 0
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour activer les conversions Ana -> Num
 +T_IM_Asservissement.data[0]=0x2A; // Adresse du registre ADCON0  
 +T_IM_Asservissement.data[1]=0xF0; // Masque -> bits 7..4 concernés
 +T_IM_Asservissement.data[2]=0x80; // Valeur ->  ADON=1 et "prescaler rate"=1:32
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour définir le mode de conversion
 +T_IM_Asservissement.data[0]=0x2B; // Adresse du registre ADCON1  
 +T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont concernés
 +T_IM_Asservissement.data[2]=0x0C; // Valeur ->  voir doc MCP25050 page 36
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour valider le séquenceur
 +T_IM_Asservissement.data[0]=0x2C; // Adresse du registre STON  
 +T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont concernés
 +T_IM_Asservissement.data[2]=0xD2; // Valeur ->  voir doc MCP25050 page 24
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +// Pour valider le séquencement sur entrées analogiques 0 et 1
 +T_IM_Asservissement.data[0]=0x2C; // Adresse du registre STON  
 +T_IM_Asservissement.data[1]=0x03; // Masque -> tous les bits sont concernés
 +T_IM_Asservissement.data[2]=0x03; // Valeur ->  voir doc MCP25050 page 24
 +Ecrire_Trame(T_IM_Asservissement);
 +do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 +Cptr_Affichage=0;
 +Ctpr_Acquisition=0;
 +Cptr_TimeOut=0;
 +// BOUCLE PRINCIPALE
 +//*******************
 +while(1)
 + {// Un trame donnant les états est recue à intervalles de temps réguliers
 + // Fonction 'Scéduleur' du module 'Asservissement' est activée
 + if(Lire_Trame(&Trame_Recue)!=1) // Un trame résultat n'est pas arrivée ?
 + {Cptr_TimeOut++;
 + if(Cptr_TimeOut==10000)
 + {clsscr(),gotoxy(2,10);
 + printf(" Pas de trame resultats de conversion depuis trop longtemps\n");
 + printf("  Il faut recharger et relancer le programme \n");
 + do{}while(1);}} // Stop 
 + else {Cptr_TimeOut=0;
 + if(Trame_Recue.ident.extend.identificateur.ident==Ident_T_OB_Asservissement)
 + // On teste si l'identificateur est correct
 + {AN1H =Trame_Recue.data[3]; // On récupére les MSB de la mesure vitesse
 + AN10L =Trame_Recue.data[4]; // On récupére les LSB AN1 et AN0
 + // Traiter les données et reconstituer les résultats
 + S_Mesure_Vitesse=(unsigned short)(AN1H); //Transfert avec transtypage
 + S_Mesure_Vitesse=S_Mesure_Vitesse<<2; // Décaler de 2 bits vers poids forts
 + S_Temp=(unsigned short)(AN10L&0xC0); // Pour ne récupérer que les 2 bits AD1 et AD0
 + S_Mesure_Vitesse=S_Mesure_Vitesse|(S_Temp>>6);
 + // Calculer la grandeur de commande
 + Ecart = S_Consigne - S_Mesure_Vitesse;
 + Resultat_Calcul = (Kp*Ecart)>>4;
 +     if(Resultat_Calcul>255)Resultat_Calcul=255;
 + if(Resultat_Calcul<0)Resultat_Calcul=0;
 + Cde_Moteur=(unsigned char)(Resultat_Calcul);
 + T_IM_Asservissement.data[0]=0x25; // Adresse du registre PWM1DC (Charger cde vitesse)
 + T_IM_Asservissement.data[1]=0xFF; // Masque -> tous les bits sont concernés
 + T_IM_Asservissement.data[2]=Cde_Moteur; // Valeur ->  Commande vitesse
 + Ecrire_Trame(T_IM_Asservissement);
 + do{}while(Lire_Trame(&Trame_Recue)==0); // Attendre réponse
 + // Acquisition de la consigne
 + Ecrire_Trame(T_IRM_Commodo_EG);
 + do{}while(Lire_Trame(&Trame_Recue)==0);
 + if(Trame_Recue.ident.extend.identificateur.ident==Ident_T_IRM8_Commodo_EG)
 + {AN0H =Trame_Recue.data[2]; // On récupére les MSB entree analogique Commodo EG
 + AN10L =Trame_Recue.data[4]; // On récupére les LSB AN1 et AN0
 +        // Traiter les données et reconstituer les résultats
 + S_Consigne=(unsigned short)(AN0H); //Transfert avec transtypage
 + S_Consigne=S_Consigne<<2; // Décaler de 2 bits vers poids forts
 + S_Temp=(unsigned short)(AN10L&0x0C); // Pour ne récupérer que les 2 bits AD1 et AD0
 + S_Consigne=S_Consigne|(S_Temp>>2);
 + }
 + }} // Fin acquisition et traitement
 +
 + Cptr_Affichage++;
 + if(Cptr_Affichage==20000)
 + {Cptr_Affichage=0;
 + gotoxy(1,12);
 +  printf("  Valeur de l'entree Consigne:                  \n");
 + printf("  Valeur de l'entree Mesure vitesse:            \n");
 + printf("  Ecart = Consigne - Mesure:                    \n");
 + printf("  Valeur de la Commande moteur:                 \n");
 + // Afficher grandeurs
 + gotoxy(1,12);
 + printf("  Valeur de l'entree Consigne: %d\n",S_Consigne);
 + printf("  Valeur de l'entree Mesure vitesse: %d\n",S_Mesure_Vitesse);
 + printf("  Ecart = Consigne - Mesure: %d\n",Ecart);
 + printf("  Valeur de la commande moteur:%d\n",Cde_Moteur);
 + printf("  On doit verifier la relation:\n");
 + printf("  Commande moteur = (Kp*Ecart)/16 avec Kp= %d\n",Kp);}  
 + } //  Fin boucle principale
 +} // Fin fonction principale
 +
 +
 +
 +</code>
 +
  
fr/supervisors/solutions/didalab/exercice2.1274990806.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