Acquérir l'état du commodo d'essuie-glace
A intervalles de temps réguliers, on interroge le module sur lequel est connecté le commodo Essuie-Glace afin de connaître son état.
Avant de pouvoir lire l'état des entrées du module 8 entrées (dont on donne le schéma structurel en 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 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 doc. technique du MPC25025 page 22). On pourra ainsi modifier les différents registres du module Asservissement.
Définition de la trame de commande (IM
) qui sera envoyée pour configurer le module Commodo-EG
Trame
:
Trame T_IM_Commodo_EG;
T_IM_ Commodo_EG
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;
Rem : Ident_T_IM_Commodo_EG
est défini dans le fichier CAN_VMD.h
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 (doc. technique MCP25050 p. 27).
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)
Suite à ces définitions, il faudra :
Ecrire_Trame(T_IM_Commodo_EG)
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.
Définition des trois octets de données associées pour :
D'après la doc. technique du circuit MCP25050 (pages 34 à 37) : Il faut initialiser le registre ADCON0,
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
Suite à ces définitions, il faudra :
Ecrire_Trame(T_IM_Commodo_EG)
Ack
en utilisant la fonction Lire_Trame(&T_Recue)
Il faut aussi initialiser le registre ADCON1 :
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)
Suite à ces définitions, il faudra :
Ecrire_Trame(T_IM_Commodo_EG)
Ack
en utilisant la fonction Lire_Trame(&T_Recue)
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 doc. technique du CAN Expander MPC25025 pages 22).
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.
T_IRM_Commodo_EG
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
Des labels définissant les différents identificateurs ont été déclarés dans le fichier CAN_VMD.h
Suite à ces définitions, il faudra :
Ecrire_Trame(T_IRM_Commodo_EG)
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 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 (doc. MCP25050 p. 22):
Les 3 autres octets ne sont pas utiles dans notre application. Le résultat de conversion est sur 10bits :
/************************************************************************************************ * 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->N 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