This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| fr:examples:can:wiper:tp3 [2010/03/03 15:12] – créée sdeniaud | fr:examples:can:wiper:tp3 [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== TP3 - Exemple ====== | + | ====== TP3 - Exemple |
| + | ===== Sujet: ===== | ||
| + | **Faire battre le balai de l' | ||
| + | |||
| + | ==== Objectifs : ==== | ||
| + | |||
| + | * Définir les différentes trames interrogatives ou de commande à faire transiter par le réseau CAN en fonction d'une action souhaitée. | ||
| + | |||
| + | * Commander un actionneur électrique (moteur à courant continu), dans les deux sens de rotation par l' | ||
| + | |||
| + | * Acquérir l' | ||
| + | |||
| + | ==== Cahier des charges : ==== | ||
| + | |||
| + | Après avoir fait tourner le moteur dans le sens positif (déplacement à droite) jusqu' | ||
| + | |||
| + | * déplacement à gauche jusqu' | ||
| + | * déplacement à droite jusqu' | ||
| + | * etc | ||
| + | |||
| + | |||
| + | ===== Eléments de solution ===== | ||
| + | ==== Analyse ==== | ||
| + | |||
| + | **Principe: | ||
| + | Le module d' | ||
| + | Ce module permet la commande d'un moteur à courant continu 24V/ 1A, dans les deux sens de rotation, en mode " | ||
| + | Il permet d' | ||
| + | → fcd (fin de course droit) relié à l' | ||
| + | → fcg (fin de course gauche) relié à l' | ||
| + | → fs (fin de surcource) relié à l' | ||
| + | Le cycle demandé conduit au diagramme des états suivant: | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | **Configurations du module " | ||
| + | Comme dans l' | ||
| + | |||
| + | **Trame n°1** | ||
| + | Il faut initialiser le registre GPDDR ("Data Direction Register" | ||
| + | |||
| + | **Trame n°2** | ||
| + | |||
| + | **Trame n°3** | ||
| + | |||
| + | **Trame n°4** | ||
| + | |||
| + | **Trame n°5** | ||
| + | D' | ||
| + | <code c> | ||
| + | bit 7 =1 TMR2ON Validation du "Timer 2" | ||
| + | bits 5:4 seront mis à 0 pour avoir un coefficient de division de fréquence égal à 1 ("TMR2 prescaler value" = 1) | ||
| + | T_IM_Asservissement.data[0]=0x22; | ||
| + | T_IM_Asservissement.data[1]=0xB3; | ||
| + | T_IM_Asservissement.data[2]=0x80; | ||
| + | </ | ||
| + | Suite à ces définitions, | ||
| + | |||
| + | **Trame n°6** | ||
| + | Cette fréquence dépend de la valeur chargée dans le registre " | ||
| + | <code c> | ||
| + | T_IM_Asservissement.data[0]=0x24; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=0xFF; | ||
| + | </ | ||
| + | La fréquence du quartz implanté sur la carte " | ||
| + | Ce qui est une fréquence correcte pour piloter un moteur en PWM (fréquence sensiblement inaudible). | ||
| + | Suite à ces définitions, | ||
| + | |||
| + | **Trame n°7** | ||
| + | <code c> | ||
| + | T_IM_Asservissement.data[0]=0x25; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=0x00; | ||
| + | </ | ||
| + | Suite à ces définitions, | ||
| + | |||
| + | **Acquisition de l' | ||
| + | |||
| + | Définition de la trame interrogative permettant de connaître l' | ||
| + | Dans ce cas, la trame envoyée par le contrôleur CAN (Circuit SJA1000 sur carte CAN_PC104) sera vue par le récepteur (circuit MCP25050 sur module) comme une IRM '' | ||
| + | |||
| + | D’après le tableau donné page 22 de la notice du MCP25050, l’identificateur lui-même contiendra l’adresse du registre lu. Cette adresse est placée sur les bits ID15 à ID8 de l’identificateur en mode étendu (bits qui seront réceptionnés et placés dans le registre RXBEID8). Le registre concerné est GPPIN d’adresse '' | ||
| + | D’autre part, les trois bits de poids faibles de l’identificateur en mode étendu devront être positionnés à 1. | ||
| + | L’identificateur défini dans le chapitre 1 devra donc être complété comme suit: | ||
| + | {{ : | ||
| + | |||
| + | → Définition de variables structurées sous le modèle | ||
| + | <code c> | ||
| + | Trame T_IRM_Acquisition_FC; | ||
| + | </ | ||
| + | Remarque: | ||
| + | |||
| + | → Accès et définition des différents éléments de la variable structurée '' | ||
| + | <code c> | ||
| + | T_IRM_Acquisition_FC.trame_info.registre=0x00; | ||
| + | T_IRM_Acquisition_FC.trame_info.champ.extend=1; | ||
| + | T_IRM_Acquisition_FC.trame_info.champ.dlc=0x01; | ||
| + | T_IRM_Acquisition _FC.ident.extend.identificateur.ident=0x00841E07; | ||
| + | </ | ||
| + | Suite à ces définitions, | ||
| + | * envoyer la trame par la fonction '' | ||
| + | * puis attendre la réponse de type " | ||
| + | |||
| + | D' | ||
| + | Vu du module (du MCP25050), la réponse à un " | ||
| + | La différence avec la trame interrogative origine est que cette trame réponse comporte le paramètre '' | ||
| + | |||
| + | **Définition de variables structurées images de l' | ||
| + | |||
| + | La trame reçue en réponse à cette trame interrogative comportera en data[0], l' | ||
| + | union byte_bits FC; | ||
| + | <code c> | ||
| + | #define Etats_FC FC.valeur // Pour l' | ||
| + | #define fs FC.bit.b7 | ||
| + | #define fcg FC.bit.b6 // Pour fin de course gauche | ||
| + | #define fcd FC.bit.b5 // Pour fin de course droit | ||
| + | </ | ||
| + | |||
| + | Afin de pouvoir détecter les changements d' | ||
| + | <code c> | ||
| + | union byte_bits FC_Mem; // Pour fins de courses mémorisés | ||
| + | #define Etats_FC_Mem FC_Mem.valeur | ||
| + | </ | ||
| + | Si l' | ||
| + | |||
| + | |||
| + | ==== Organigramme: | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ==== Programme en " | ||
| + | |||
| + | <code c> | ||
| + | / | ||
| + | * TPs sur EID210 / Réseau CAN - VMD (Véhicule Multiplexé Didactique) | ||
| + | ************************************************************************************* | ||
| + | * | ||
| + | ************************************************************************************* | ||
| + | * TP Exemple n°3: | ||
| + | *------------------------------------------------------------------------------------ | ||
| + | * | ||
| + | * ********************* | ||
| + | * On souhaite que l' | ||
| + | * - rotation droite jusqu' | ||
| + | * - arrêt sur fin de course droit et démarrage en rotation gauche | ||
| + | * - rotation gauche jusqu' | ||
| + | * - arrêt sur fin de course gauche et démarrage en rotation droite | ||
| + | * etc ... | ||
| + | * La structure de programme sera de type " | ||
| + | * On affichera à l' | ||
| + | *------------------------------------------------------------------------------------- | ||
| + | * NOM du FICHIER : TP_Exemple 3.C | ||
| + | * ***************** | ||
| + | **************************************************************************************/ | ||
| + | |||
| + | // Déclaration des fichiers d' | ||
| + | #include < | ||
| + | # | ||
| + | # | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | |||
| + | // Déclaration des variables | ||
| + | // Pour les Indicateurs divers (variables binaires) | ||
| + | union byte_bits Indicateurs, | ||
| + | #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 fins de course | ||
| + | #define Etat_FC FC.valeur // Pour l' | ||
| + | #define fs FC.bit.b7 // | ||
| + | #define fcg FC.bit.b6 // | ||
| + | #define fcd FC.bit.b5 // | ||
| + | #define Etat_FC_Mem FC_Mem.valeur // Pour la mémorisation des fins de courses | ||
| + | // Déclarations des diverses trames de communication | ||
| + | Trame Trame_Recue; | ||
| + | #define Ident_Trame_Recue Trame_Recue.ident.extend.identificateur.ident | ||
| + | // Trmes de type " | ||
| + | Trame T_IM_Asservissement; | ||
| + | Trame T_IRM_Acquisition_FC; | ||
| + | // Déclaration constantes | ||
| + | #define Module_Vitesse 100 | ||
| + | |||
| + | // | ||
| + | // FONCTION PRINCIPALE | ||
| + | // | ||
| + | main() | ||
| + | { | ||
| + | // INITIALISATIONS | ||
| + | // | ||
| + | // Déclaration de variables locales à la fonction principale | ||
| + | int Cptr_Affichage=0, | ||
| + | |||
| + | Init_Aton_CAN(); | ||
| + | clsscr(); | ||
| + | // Trame de type " | ||
| + | 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/ | ||
| + | T_IM_Asservissement.data[0]=0x1F; | ||
| + | // doc MCP25050 Page 16 | ||
| + | T_IM_Asservissement.data[1]=0xEF; | ||
| + | T_IM_Asservissement.data[2]=0xE3; | ||
| + | // GP7=fs Entrée; GP6=fcg Entree; GP5=fcd Entrée; | ||
| + | // GP3=PWM2 Sortie; GP2=PWM1 Sortie; GP1=AN1 Entrée; GP0=AN0 Entrée; | ||
| + | I_Message_Pb_Affiche=0; | ||
| + | do {Ecrire_Trame(T_IM_Asservissement); | ||
| + | Cptr_TimeOut=0; | ||
| + | do{Cptr_TimeOut++; | ||
| + | if(Cptr_TimeOut==2000) | ||
| + | { gotoxy(2, | ||
| + | printf(" | ||
| + | printf(" | ||
| + | do{}while(Lire_Trame(& | ||
| + | for(Cptr_TimeOut=0; | ||
| + | Ecrire_Trame(T_IM_Commodo_EG); | ||
| + | Cptr_TimeOut=0; | ||
| + | do{Cptr_TimeOut++; | ||
| + | if(Cptr_TimeOut==2000) | ||
| + | { gotoxy(2, | ||
| + | printf(" | ||
| + | printf(" | ||
| + | do{}while(1); | ||
| + | } | ||
| + | } | ||
| + | // Pour mettre à 0 les sorties | ||
| + | T_IM_Asservissement.data[0]=0x1E; | ||
| + | T_IM_Asservissement.data[1]=0x1C; | ||
| + | T_IM_Asservissement.data[2]=0x00; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour définir sortie GP2 en PWM1 | ||
| + | T_IM_Asservissement.data[0]=0x21; | ||
| + | T_IM_Asservissement.data[1]=0xB3; | ||
| + | T_IM_Asservissement.data[2]=0x80; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour définir fréquence signal sortie PWM1 | ||
| + | T_IM_Asservissement.data[0]=0x23; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=0xFF; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour définir sortie GP3 en PWM2 | ||
| + | T_IM_Asservissement.data[0]=0x22; | ||
| + | T_IM_Asservissement.data[1]=0xB3; | ||
| + | T_IM_Asservissement.data[2]=0x80; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour définir fréquence signal sortie PWM2 | ||
| + | T_IM_Asservissement.data[0]=0x24; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=0xFF; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour initialiser rapport cyclique PWM1 | ||
| + | T_IM_Asservissement.data[0]=0x25; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=Module_Vitesse; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour initialiser rapport cyclique PWM2 à 0 | ||
| + | T_IM_Asservissement.data[0]=0x26; | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | T_IM_Asservissement.data[2]=0; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Pour Valider le circuit de puissance | ||
| + | T_IM_Asservissement.data[0]=0x1E; | ||
| + | T_IM_Asservissement.data[1]=0x10; | ||
| + | T_IM_Asservissement.data[2]=0x10; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | do{}while(Lire_Trame(& | ||
| + | // Masque pour les commandes IM futures | ||
| + | T_IM_Asservissement.data[1]=0xFF; | ||
| + | // Pour acquérir l' | ||
| + | // Trame de type " | ||
| + | T_IRM_Acquisition_FC.trame_info.registre=0x00; | ||
| + | T_IRM_Acquisition_FC.trame_info.champ.extend=1; | ||
| + | T_IRM_Acquisition_FC.trame_info.champ.dlc=1; | ||
| + | T_IRM_Acquisition_FC.trame_info.champ.rtr=1; | ||
| + | T_IRM_Acquisition_FC.ident.extend.identificateur.ident=Ident_T_IRM1_Asservissement; | ||
| + | | ||
| + | do{}while(Lire_Trame(& | ||
| + | Etat_FC=~Trame_Recue.data[0]; | ||
| + | Etat_FC_Mem=Etat_FC; | ||
| + | // Initialisation des variables diverses | ||
| + | I_Sens_Rotation=0; | ||
| + | |||
| + | // Pour afficher titre | ||
| + | gotoxy(1, | ||
| + | printf(" | ||
| + | printf(" | ||
| + | printf(" | ||
| + | printf(" | ||
| + | printf(" | ||
| + | |||
| + | // BOUCLE PRINCIPALE | ||
| + | // | ||
| + | while(1) | ||
| + | { | ||
| + | // Pour " | ||
| + | Ecrire_Trame(T_IRM_Acquisition_FC); | ||
| + | Cptr_TimeOut=0; | ||
| + | do{Cptr_TimeOut++; | ||
| + | if(Cptr_TimeOut==10000) | ||
| + | {clsscr(), | ||
| + | printf(" | ||
| + | printf(" | ||
| + | do{}while(1); | ||
| + | else { if(Trame_Recue.ident.extend.identificateur.ident==Ident_T_IRM1_Asservissement) | ||
| + | // Si identificateur attendu | ||
| + | {Etat_FC=~Trame_Recue.data[0]; | ||
| + | if(Etat_FC!=Etat_FC_Mem) // S'il y a eu une modification | ||
| + | // de l' | ||
| + | {Etat_FC_Mem=Etat_FC; | ||
| + | // Traiter le changement de l' | ||
| + | if(I_Sens_Rotation) // Si on tourne en négatif | ||
| + | {if(fcg) // Si on est arrivé en fin de course gauche | ||
| + | {T_IM_Asservissement.data[2]=0; | ||
| + | T_IM_Asservissement.data[0]=0x26; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | while(Lire_Trame(& | ||
| + | T_IM_Asservissement.data[2]=Module_Vitesse; | ||
| + | T_IM_Asservissement.data[0]=0x25; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | while(Lire_Trame(& | ||
| + | I_Sens_Rotation=!I_Sens_Rotation; | ||
| + | }} | ||
| + | else {// On tourne en positif | ||
| + | if(fcd) // Si on est arrivé en fin de course droit | ||
| + | {T_IM_Asservissement.data[2]=0; | ||
| + | T_IM_Asservissement.data[0]=0x25; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | while(Lire_Trame(& | ||
| + | T_IM_Asservissement.data[2]=Module_Vitesse; | ||
| + | T_IM_Asservissement.data[0]=0x26; | ||
| + | Ecrire_Trame(T_IM_Asservissement); | ||
| + | while(Lire_Trame(& | ||
| + | I_Sens_Rotation=!I_Sens_Rotation; | ||
| + | }} | ||
| + | }}} // Fin " | ||
| + | } // Fin boucle principale | ||
| + | } // Fin fonction principale | ||
| + | </ | ||