TP Bus CAN - page d`accueil

Transcription

TP Bus CAN - page d`accueil
Transmission de donnée
Utilisation bus CAN : tp1
On se propose dans ce TP de mettre en uvre le « dongle » qui permet depuis le port parallèle du PC d’accéder
à un bus CAN.
Le constructeur fournit avec le matériel un driver sous forme d’une DLL que nous utiliserons pour réaliser un
programme en mode console avec Visual C++.
L’objectif étant d’échanger des informations entre 2 PC connectés à un bus CAN.
Le constructeur fournit également un logiciel utilisant le même « dongle » pour analyser les trames circulant sur
un bus CAN.
Matériel et éléments logiciels à disposition.
On dispose, au niveau matériel, des éléments suivants :
2 PC avec les outils de développent logiciels Visual C++
2 « dongles » PCAN avec un cordon de connexion CAN (DB9)
On dispose, au niveau logiciel, des éléments suivants :
Des fichiers fournis avec le produit dans un répertoire que l’on vous indiquera
Préparation
On donne le listing du programme principal de l’application ;
// utilisation de l'API en mode console : 4 aout 2005
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include "dongle\PCAN_DNG.H"
#define CAN_PORT 0x378
#define CAN_INT 7
//typdef of Functions
typedef DWORD (__stdcall *PCAN_Init)(WORD wBTR0BTR1, int CANMsgType, int CANHwType, DWORD IO_Port, WORD Interupt);
typedef DWORD (__stdcall *PCAN_Close)();
typedef DWORD (__stdcall *PCAN_Status)();
typedef DWORD (__stdcall *PCAN_Write)(TPCANMsg* pMsgBuff);
typedef DWORD (__stdcall *PCAN_Read)(TPCANMsg* pMsgBuff);
typedef DWORD (__stdcall *PCAN_VersionInfo)(LPSTR lpversioninfo);
// Function declaration
bool GetFunctionAdress(HINSTANCE h_module);
void check_err(DWORD err, char *txtbuff);
int LoadDLL(void);
int UnloadDLL(void);
//declaration
PCAN_Init g_CAN_Init;
PCAN_Close g_CAN_Close;
PCAN_Status g_CAN_Status;
#njc Lycée « la Briquerie »
TP : utilisation bus CAN 1
& page 1/5
PCAN_Write g_CAN_Write;
PCAN_Read g_CAN_Read;
PCAN_VersionInfo g_CAN_VersionInfo;
HINSTANCE g_i_DLL;
char g_LibFileName[] = "dongle\\PCAN_DNG.DLL";
unsigned int g_MsgCount =0;
// main entry
// Parameter: none
// ret value: 0 if OK
int main(int argc, char* argv[])
{
int ret;
char c;
char buffer[255];
char buffer2[10];
// CAN_Message
TPCANMsg myMsg;
//Stop Flag
int g_stop = false;
printf("********** CAN tp1 by njc **********\n");
printf("*** presser <ESC> to end\n");
printf("*** presser <S> pour envoyer le Msg ID:0x100 LEN:2 DATA0:0x010 DATA1:0x020\n");
printf("*** les messages recus sont affiches !\n\n");
//Load DLL and get Proc Adress of used function
ret = LoadDLL();
if(ret!=0)
{
return 1;
}
printf("INFO: DLL loaded\n");
// open CAN Port
if(g_CAN_Init !=NULL) // check if function pointer is vallid
{
// init PCAN-Dongle in MUX mode Port 0x378 and Interruot 7
ret=g_CAN_Init(CAN_BAUD_500K, CAN_INIT_TYPE_ST, HW_DONGLE_SJA, CAN_PORT, CAN_INT);
check_err(ret, buffer);
printf("CAN_Init %s\n",buffer);
if(ret != CAN_ERR_OK)
{
g_stop = true;
}
}
// main loop
do{
// Now check what to do....
if(_kbhit())
{
c=_getch();
switch(c)
{
case 27:// ESC pressed
g_stop = true;
break;
case 's': // if sS is pressed ....send CAN Msg
printf("send CAN-DATA ID:0x100 LEN:2 Data:0x010 0x020\n");
if(g_CAN_Write !=NULL) // function pointer vallid
{
myMsg.ID = 0x100;
myMsg.MSGTYPE = 0;
myMsg.LEN = 2;
myMsg.DATA[0] = 0x010;
myMsg.DATA[1] = 0x020;
ret=g_CAN_Write(&myMsg);
check_err(ret, buffer);
printf("CAN_Send %s\n",buffer);
}
break;
}
}
// get CAN-Status
ret = g_CAN_Status();
if(ret != CAN_ERR_OK)
{
check_err(ret, buffer);
#njc Lycée « la Briquerie »
TP : utilisation bus CAN 1
& page 2/5
printf("CAN_Status: %s\n",buffer);
}
//check if Data in driver buffer ...if yes print out
if(g_CAN_Read !=NULL) // vallid pointer
{
while ((g_CAN_Read(&myMsg) & CAN_ERR_QRCVEMPTY)==0 )//read until buffer is empty
{
// check if Status ID
if(myMsg.MSGTYPE != 0) // no std. msg
{
check_err(myMsg.DATA[2], buffer);
printf("CAN Status Msg: %s\n",buffer);
}
else
{
printf("read CAN-DATA ID:0x%02x LEN:%d ",myMsg.ID,myMsg.LEN);
buffer[0]='\0';
// check how many Data information are in MSG
for(int i=0;i<myMsg.LEN;i++)
{
sprintf(buffer2,"0x%03x ",myMsg.DATA[i]);
strcat(buffer,buffer2);
}
printf("Data:%s\n",buffer);
}
}
}
}while(!g_stop); // loop until stop flag is set
// close CAN Port
ret=g_CAN_Close();
check_err(ret, buffer);
printf("CAN_Close %s\n",buffer);
// unload DLL
ret = UnloadDLL();
if(ret!=0)
{
return 1;
}
printf("INFO: DLL unloaded\n");
printf("Programm stoped..\n");
kbhit();
return 0;
}
// Function: Load DLL
// Parameter: none
// ret value: 0 if OK, -1 if DLL not found or can not open, -2 if function pointer not found
// load the DLL and get function pointers
int LoadDLL()
{
if(g_i_DLL==NULL)
{
g_i_DLL = LoadLibrary(g_LibFileName);
if(g_i_DLL == NULL)
{
printf("ERROR: can not load DLL\n");
return -1;
}
else
{
printf("DLL Handle: 0x%x\n",g_i_DLL);
if(GetFunctionAdress( g_i_DLL )==true)
{
printf("DynaLoad for PCAN port: 0x%x int: %d\n",CAN_PORT,CAN_INT);
}
else
{
printf("ERROR: can not load Function Adress\n");
return -2;
}
}
}
return 0;
}
// Function: Unload DLL
// Parameter: none
// ret value: 0 if OK
// unload the DLL and free all pointers
#njc Lycée « la Briquerie »
TP : utilisation bus CAN 1
& page 3/5
int UnloadDLL()
{
if(g_i_DLL)
{
FreeLibrary(g_i_DLL);
g_i_DLL = NULL;
g_CAN_Init=NULL;
g_CAN_Close=NULL;
g_CAN_Status=NULL;
g_CAN_Write=NULL;
g_CAN_Read=NULL;
g_CAN_VersionInfo=NULL;
return 0;
}
return -1;
}
// Function: GetFunctionAdress
// Parameter: instance of DLL
// ret value: true if OK false if pointer not vallid
// load the function pointer from the DLL spec. by handle
bool GetFunctionAdress(HINSTANCE h_module)
{
//charge les fonctions
if(h_module == NULL)
return false;
g_CAN_Init = (PCAN_Init) GetProcAddress(h_module, "CAN_Init");
if(g_CAN_Init == NULL)
return false;
g_CAN_Close = (PCAN_Close) GetProcAddress(h_module, "CAN_Close");
if(g_CAN_Close == NULL)
return false;
g_CAN_Status = (PCAN_Status) GetProcAddress(h_module, "CAN_Status");
if(g_CAN_Status == NULL)
return false;
g_CAN_Write = (PCAN_Write) GetProcAddress(h_module, "CAN_Write");
if(g_CAN_Write == NULL)
return false;
g_CAN_Read = (PCAN_Read) GetProcAddress(h_module, "CAN_Read");
if(g_CAN_Read == NULL)
return false;
g_CAN_VersionInfo = (PCAN_VersionInfo) GetProcAddress(h_module, "CAN_VersionInfo");
if(g_CAN_VersionInfo == NULL)
return false;
return true;
}
// Function: check_err
// Parameter: erroro code, pointer to text buffer
// ret value: none
// translate PCAN-Light error code (numeric) to text information
void check_err(DWORD err, char *txtbuff)
{
#define CAN_ERR_HWINUSE 0x0400 // Hardware ist von Netz belegt
#define CAN_ERR_NETINUSE 0x0800 // an Netz ist Client angeschlossen
#define CAN_ERR_ILLHW 0x1400 // Hardwarehandle war ungueltig
#define CAN_ERR_ILLNET 0x1800 // Netzhandle war ungueltig
#define CAN_ERR_ILLCLIENT 0x1C00 // Clienthandle war ungueltig
strcpy(txtbuff, "Error: ") ;
if ( err == CAN_ERR_OK )
strcpy(txtbuff, "OK ") ;
if ( err & CAN_ERR_XMTFULL ) strcat(txtbuff, "XMTFULL ") ;
if ( err & CAN_ERR_OVERRUN ) strcat(txtbuff, "OVERRUN ") ;
if ( err & CAN_ERR_BUSLIGHT ) strcat(txtbuff, "BUSLIGHT ") ;
if ( err & CAN_ERR_BUSHEAVY ) strcat(txtbuff, "BUSHEAVY ") ;
if ( err & CAN_ERR_BUSOFF ) strcat(txtbuff, "BUSOFF ") ;
if ( err & CAN_ERR_QRCVEMPTY ) strcat(txtbuff, "QRCVEMPTY ") ;
if ( err & CAN_ERR_QOVERRUN ) strcat(txtbuff, "QOVERRUN ") ;
if ( err & CAN_ERR_QXMTFULL ) strcat(txtbuff, "QXMTFULL ") ;
if ( err & CAN_ERR_REGTEST ) strcat(txtbuff, "REGTEST ") ;
if ( err & CAN_ERR_NOVXD ) strcat(txtbuff, "NOVXD ") ;
if ( (err & CAN_ERRMASK_ILLHANDLE) == CAN_ERR_HWINUSE ) strcat(txtbuff, "HWINUSE ") ;
if ( (err & CAN_ERRMASK_ILLHANDLE) == CAN_ERR_NETINUSE ) strcat(txtbuff, "NETINUSE ") ;
if ( (err & CAN_ERRMASK_ILLHANDLE) == CAN_ERR_ILLHW )strcat(txtbuff, "ILLHW ") ;
#njc Lycée « la Briquerie »
TP : utilisation bus CAN 1
& page 4/5
if ( (err & CAN_ERRMASK_ILLHANDLE) == CAN_ERR_ILLCLIENT )strcat(txtbuff, "ILLCLIENT ") ;
if ( (err & CAN_ERRMASK_ILLHANDLE) == CAN_ERR_ILLNET ) strcat(txtbuff, "ILLNET ") ;
if ( err & CAN_ERR_RESOURCE ) strcat(txtbuff, "RESOURCE ") ;
if ( err & CAN_ERR_ILLPARAMTYPE ) strcat(txtbuff, "ILLPARAMTYPE ") ;
if ( err & CAN_ERR_ILLPARAMVAL ) strcat(txtbuff, "ILLPARAMVAL ") ;
return;
}
On demande :
Comment est pris en compte le matériel relatif au « dongle ».
De lister les fonctions fournies par l’API du constructeur en indiquant sommairement leur rôle.
Quelles sont les données manipulées par la fonction g_CAN_Read
De décrire les actions du programme principal.
De décrire les actions de l’utilisateur sur le programme.
Interconnexion et test du matériel au moyen des éléments logiciels fournis.
On demande de prévoir la procédure à utiliser pour réaliser le test des connexions et du bon fonctionnement des
modules. On se reporte pour cela aux documentations fournies par le constructeur.
Test du programme.
On demande de mettre en uvre la liaison par bus CAN entre 2 PC en utilisant le listing étudié en préparation
en utilisant l’environnement de développement Visual C++ (version 6).
On produira un document de synthèse présentant les procédures utilisées.
Exercice complémentaire
On se propose de développer une application graphique permettant de produire les mêmes effets que notre
programme. On pourra utiliser l’interface donnée en exemple ci-dessous :
L’action sur le bouton CAN_VersionInfo affiche les caractéristiques du driver grâce à une fonction de l’API
constructeur dans la zone de texte qui est juste en dessous.
#njc Lycée « la Briquerie »
TP : utilisation bus CAN 1
& page 5/5

Documents pareils