Table of Contents

Exemple 1 (TP1)

Sujet

Acquérir l'état du commodo d'essuie-glace

Objectifs

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.


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 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.

Configuration des liaisons en entrées

Définition de la trame de commande (IM) qui sera envoyée pour configurer le module Commodo-EG

Trame 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 :

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 :

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 :

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 :

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 doc. technique du CAN Expander MPC25025 pages 22).

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.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 :

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 :

AN0

Organigramme

Organigramme

Programme en 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->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