Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
fr:examples:can:wiper:tp1 [2010/03/10 19:05] sdeniaudfr:examples:can:wiper:tp1 [2020/07/20 12:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== TP1 - Exemple 1 ======
 +
 +===== Sujet =====
 +
 +**Acquérir l'état du commodo d'essuie-glace
 +**
 +==== Objectifs ====
 +
 +  * Définir les trames de commande qui permettent d'initialiser un nœud CAN
 +  * Définir, puis envoyer une trame interrogative à un module d'entrées, accessible à une adresse définie.
 +  * Tester si une trame a été reçue
 +  * Extraire d'une trame réponse les informations attendues
 +  * Visualiser sur l'écran les trames reçues ainsi que les trames envoyées
 +  * Visualiser sur l'écran les données attendues
 +
 +==== Cahier des charges ====
 +
 +A intervalles de temps réguliers, on interroge le module sur lequel est connecté le commodo Essuie-Glace afin de connaître son état.
 +  * L'entrée analogique sera convertie
 +  * Les trames reçues ou envoyées sur le bus CAN sont affichées
 +  * La temporisation est de type //logiciel// (comptage du nombre de passages dans la boucle principale)
 +  * Les différentes commandes imposées par la position de la manette commodo seront affichées individuellement
 +
 +
 +----
 +
 +
 +===== Eléments de solution =====
 +
 +==== Analyse ====
 +
 +Avant de pouvoir lire l'état des entrées du module 8 entrées (dont on donne le schéma structurel en [[annex4|annexe 4]]) sur lequel est relié le commodo essuie-glace, il faut préalablement configurer  le CAN expender MCP25050
 +Cette configuration a pour but de définir en entrée les 8 bits du port (GP0 à GP7). Pour configurer un bit du port en entrée, il faut écrire un "1" sur le bit correspondant du registre GPDDR (Data Direction Register) (voir tableau Register 5-1 à la page 27  de la {{:fr:hardware:didalab:mcp2502x_5x.pdf|doc. technique}} du 25050)
 +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 ''IM'' (Input message), avec la fonction ''Write register'' (voir {{:fr:hardware:didalab:mcp2502x_5x.pdf|doc. technique}} du MPC25025 page 22). On pourra ainsi modifier les différents registres du module Asservissement.
 +
 +=== Configuration des liaisons en entrées ===
 +
 +**Définition de la trame de commande (''IM'') qui sera envoyée pour configurer le module Commodo-EG**
 +    * Définition de variables structurées sous le modèle ''Trame'' :
 +''Trame T_IM_Commodo_EG;''
 +    * Définition des éléments d'identification de la variable structurée ''T_IM_ Commodo_EG''
 +
 +<code c>
 +T_IM_Commodo_EG.trame_info.registre=0x00; //On initialise tous les bits à 0
 +T_IM_Commodo_EG.trame_info.champ.extend=1; //On travaille en mode étendu
 +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 octets de données 
 +T_IM_Commodo_EG.ident.extend.identificateur.ident=Ident_T_IM_Commodo_EG;
 +</code>
 +
 +Rem : ''Ident_T_IM_Commodo_EG '' est défini dans le fichier ''[[annex2|CAN_VMD.h]]''
 +     * Définition des paramètres associés à la trame de commande
 +Il faut initialiser le registre GPDDR (Data Direction Register) en écrivant un 1 si bit d'entrée et un 0 si bit de sortie ({{:fr:hardware:didalab:mcp2502x_5x.pdf|doc. technique}} MCP25050 p. 27). 
 +
 +<code c>
 +T_IM_Commodo_EG.data[0]=0x1F; // Adresse du registre GPDDR en écriture (doc MCP25050 page 16)
 +T_IM_Commodo_EG.data[1]=0x7F; // Masque: bit 7 non concerné (doc MCP25050 page 16)
 +T_IM_Commodo_EG.data[2]=0x7F; // Valeur: à charger dans le registre adressé (Tous les bits du port sont des entrées)
 +</code>
 +
 +Suite à ces définitions, il faudra :
 +     * envoyer la trame par la fonction ''Ecrire_Trame(T_IM_Commodo_EG)''   
 +     * puis attendre la réponse de type ''Ack''  en utilisant la fonction ''Lire_Trame(&T_Recue)''   
 +L'entrée GP0 étant une entrée analogique (AN0), il faudra mettre en œuvre la fonction de conversion analogique -> numérique.
 +
 +=== Activation de la conversion Analogique -> Numérique ===
 +
 +
 +Définition des trois octets de données associées pour :
 +  * activer et  configurer la conversion Analogique vers Numérique 
 +D'après la {{:fr:hardware:didalab:mcp2502x_5x.pdf|doc. technique}} du circuit MCP25050 (pages 34 à 37) :
 +Il faut initialiser le registre ADCON0,
 +<code c>
 +T_IM_ Commodo_EG.data[0]=0x2A; // Adresse du registre ADCON0 en écriture ({{:fr:hardware:didalab:mcp2502x_5x.pdf|doc.}} MCP25050 p15) 0EH + décalage = 0EH + 1CH = 2AH
 +T_IM_ Commodo_EG.data[1]=0xF0; // Masque: Seul le bit 7 est concerné
 +T_IM_ Commodo_EG nt.data[2]=0x80; // Valeur: ADON=1 -> Activation convertisseur et prescaler rate = 1:32
 +</code>
 +
 +Suite à ces définitions, il faudra  :
 +     * envoyer la trame par la fonction ''Ecrire_Trame(T_IM_Commodo_EG)''  
 +     * puis attendre la réponse de type ''Ack'' en utilisant la fonction ''Lire_Trame(&T_Recue)'' 
 + 
 +Il faut aussi initialiser le registre ADCON1 :  
 +<code c>
 +T_IM_ Commodo_EG.data[0]=0x2B; // Adresse du registre ADCON1 en écriture ({{:fr:hardware:didalab:mcp2502x_5x.pdf|doc.}} MCP25050 p. 15) 0FH + décalage = 0EH + 1CH = 2BH
 +T_IM_ Commodo_EG.data[1]=0xFF; // Masque:  les 8 bits sont concernés
 +T_IM_ Commodo_EG.data[2]=0xO3; // Valeur: (doc MCP25050 p36)
 + b7=ADCS1=0; b6=ADCS0=0 → Fréquence Fosc/2
 + b5=VCFG1=0; b4=VCFG0=0 → Plage de tension en entrée 0/+5V
 + PCFG3:PCFG0=1100       → Conversion des entrées analogiques 1 et 0 (sur GP1 et GP0)
 +</code>
 +
 +Suite à ces définitions, il faudra :
 +     * envoyer la trame par la fonction ''Ecrire_Trame(T_IM_Commodo_EG)''   
 +     * puis attendre la réponse de type ''Ack''  en utilisant la fonction ''Lire_Trame(&T_Recue)''   
 +
 +
 +=== Acquisition de l'état des entrées sur le module Commodo-EG ===
 +
 +
 +A intervalles de temps réguliers, on interroge le module 8 entrées sur lequel est connecté le commodo Essuie-Glace. Dans la réponse on attend également le résultat de conversion de l'entrée analogique.
 +
 +** Définition de la trame interrogative qui sera envoyée  **
 +
 +
 +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 un ''IRM'' (Information Request Message), avec la fonction "Read A/D Regs" (voir {{:fr:hardware:didalab:mcp2502x_5x.pdf|doc. technique}} du CAN Expander MPC25025 pages 22). 
 +
 +  * Définition de variables structurées sous le modèle ''Trame'':
 +        ''Trame T_IRM_Commodo_EG;'' Trame destinée à l’interrogation du module 8 entrées sur lequel est connecté le commodo lumière
 +Rem :  La variable structurée  ''T_IRM_Commodo_EG'' comportera 5 octets utiles seulement, 1'octet pour ''trame_info'' et  4 octets pour l'identificateur en mode étendu (qui comprendra l'adresse du registre concerné par la lecture.
 +
 +  * Accès et définition des différents éléments de la variable structurée ''T_IRM_Commodo_EG'' 
 +<code c>
 +T_IRM_Commodo_EG.trame_info.registre=0x00;  //On initialise tous les bits à 0
 +T_IRM_Commodo_EG.trame_info.champ.extend=1; //On travaille en mode étendu
 +T_IRM_Commodo_EG.trame_info.champ.rtr=0x01; // Type trame ->  Interrogative
 +T_IRM_Commodo_EG.trame_info.champ.dlc=0x08; //Il y aura 8 octets de données
 +T_IRM_Commodo_EG.ident.extend.identificateur.ident= Ident_T_IRM8_Commodo_EG; //! c'est sur 29 bits Pour définir l'adresse du commodo
 +</code>
 +
 +Des labels définissant les différents identificateurs ont été déclarés dans le fichier ''[[annex2|CAN_VMD.h]]''
 +
 +Suite à ces définitions, il faudra :
 +     * envoyer la trame par la fonction ''Ecrire_Trame(T_IRM_Commodo_EG)''   
 +     * puis attendre la réponse de type ''OM'' en utilisant la fonction  ''Lire_Trame(&T_Recue)''  
 +
 +**Trame reçue en réponse à l'interrogation**
 +
 +
 +D'après la définition des identificateurs donnée en [[annex1|Annexe 1]], une trame de réponse à une ''IRM'' a le même identificateur que la trame interrogative qui en a été à l'origine. 
 +Vu du module (du MCP25050), la réponse à un ''IRM'' (Information Request Message) est un ''OM'' (Output Message). 
 +La trame réponse, suite à l'IRM, comportera en données associées 8 octets ({{:fr:hardware:didalab:mcp2502x_5x.pdf|doc.}} MCP25050 p. 22):
 +     * octet de rang 0  (data[0])→ valeur IOINTFL  non utilisée dans notre cas
 +     * octet de rang 1  (data[1])→ valeur GPIO → Valeur des entrées logiques
 +     * octet de rang 2  (data[2])→ valeur AN0H → 8 bits MSB conversion entrée anologique 0
 +     * octet de rang 3  (data[3])→ valeur AN1H → 8 bits MSB conversion entrée anologique 1
 +     * octet de rang 4  (data[4])→ valeur AN10H → 2 fois 2 bits LSB conversion entrées ana. 1 et 0
 +Les 3 autres octets ne sont pas utiles dans notre application.
 +Le résultat de conversion est sur 10bits : 
 +     * pour résultat AN0 
 +{{  :fr:examples:can:wiper:an0.png|AN0}}
 +
 +==== Organigramme ====
 +
 +{{  :fr:examples:can:wiper:orga.png?600  |Organigramme}}
 +
 +==== Programme en C ====
 +
 +<code c>
 +/************************************************************************************************
 +*       TPs sur  EID210 / Réseau CAN - VMD  (Véhicule Multiplexé Didactique) 
 +*************************************************************************************************
 +*       APPLICATION: Commande Essuie-glace à distance
 +*************************************************************************************************
 +*  TP Exemple n°1:  Acquérir l'état des entrées binaires ainsi que la valeur de l'entrée analogique
 +*              du commodo Essuie-Glace  
 +*              Afficher séparément les états de ces entrées binaires
 +*    Afficher la valeur de l'entrée analogique
 +*------------------------------------------------------------------------------------------------
 +*   CAHIER DES CHARGES :      
 +*  *********************      
 +*   On souhaite qu'à intervalles de temps réguliers on interroge le module 8 entrées sur lequel 
 +*   est relié le commodo de commande Essuie-Glace
 +*   -> Les trames reçues et envoyées sur le bus CAN sont affichées
 +*   -> Les états des entrées binaires et de l'entrée analogique sont affichés
 +*   -> La temporisation est de type logiciel
 +* (comptage du nombre de passages dans la boucle principale)
 +*----------------------------------------------------------------------------------------------
 +*  NOM du FICHIER :  TP_Exemple 2.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"
 +//==========================
 +//  FONCTION PRINCIPALE
 +//==========================
 +main()
 +{// Définition de variables locales
 +int Compteur_Passage;
 +unsigned short S_Temp,Valeur_ANA;
 +unsigned int Cptr_TimeOut;
 +unsigned char AN0H,AN10L;  // Pour récupérer le résultat de la conversion A->N
 +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 interroger Module 8E sur Commodo Essuie Glace  
 + // IM -> Information Message -> Trame de commande
 +
 +// Initialisations
 +//*****************
 +clsscr();
 +/* Initialisation DU SJA1000 de la carte PC104 */
 +Init_Aton_CAN();
 +// 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; // 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)
 + { 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<100000;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
 +
 + }
 +clsscr();
 +// Pour afficher le titre du TP
 +gotoxy(1,4);
 +printf("  ********************************************************************\n");
 +printf("   TPs sur Reseau CAN   Application: Commande Essui-Glace a distance  \n");
 +printf("  --------------------------------------------------------------------\n");
 +printf("   TP Exemple n°1                                                    \n"); 
 +printf("     ACQUERIR les entrees binaires du COMMODO EG                      \n");
 +printf("     ACQUERIR la valeur de l'entree analogique du COMMODO EG          \n");
 +printf("     AFFICHER les valeurs acquises                \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
 +// Pour trame interrogative envoyée au commodo EG -> '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 demande la valeur de 8 registre
 +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
 +Ecrire_Trame(T_IRM_Commodo_EG); // On envoi une première trame
 +// Initialiser les variables diverses
 +Compteur_Passage=0;
 +// Boucle principale
 +//*******************
 +   do
 + {  // On teste si une trame a été reçue
 +    if (1==Lire_Trame(&Trame_Recue))  // La fonction renvoie 1 dans ce cas
 + {gotoxy(4,18);
 + printf("Trame recue en reponse a la demande: c'est une 'OM' (Output Messsage) \n");
 + Affiche_Trame(Trame_Recue);
 + if (Trame_Recue.ident.extend.identificateur.ident==Ident_T_IRM8_Commodo_EG)
 + { // On a reçu l'état du commodo donc on affiche les nouveaux états
 + Commodo_EG.valeur=~Trame_Recue.data[1];  // Les entrées binaires
 + AN0H =Trame_Recue.data[2]; // On récupére les MSB de la conversion A-> voie AN0 
 + AN10L =Trame_Recue.data[4]; // On récupére les LSB AN1 et AN0
 + // Traiter les données et reconstituer le résultat de conversion sur 10 bits
 + Valeur_ANA=(unsigned short)(AN0H); //Transfert avec transtypage
 + Valeur_ANA=Valeur_ANA<<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
 + Valeur_ANA=Valeur_ANA|(S_Temp>>2);  // On reconstitue les 10 du resultat de conversion
 + // On affiche les résultats
 + gotoxy(4,22);
 + printf("Etat des differentes entrees imposees par le commodo:\n");
 + printf("    Etat entree binaires (en Hexa) =%2.2x\n",Commodo_EG.valeur);
 + printf("    Valeur de l'entee analogique =%4d\n",Valeur_ANA);
 + }
 + }
 + Compteur_Passage++;
 + if (Compteur_Passage==50000)
 +      {Compteur_Passage=0;// C'est la fin de temporisation
 + gotoxy(4,14);
 + printf("Trame de demande etat commodo: c'est une  'IRM'   Input Request Mesage\n");
 + Affiche_Trame(T_IRM_Commodo_EG);  // La trame interrogative est affichée à l'écran 
 + Ecrire_Trame(T_IRM_Commodo_EG);
 +      }
 + }while(1);     // FIN de la boucle principale
 +}
 +// FIN fonction principale
 +</code>
 +
 +
  
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