Port série thread

Description

c'est un code qui regoupe le port série et les threads... c'est tout

Source / Exemple :


// FICHIERS D'INCLUSION
//------------------------------------------------------------------------------
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <winerror.h>

// CONSTANTES
//-------------------------------------------------------------------------------
// Définition du code d'erreurs
typedef enum
{
    e_ErrCom_None,				// Pas d'erreur
    e_ErrCom_Creation,			// Erreur lors de la création du flux
    e_ErrCom_Utilise,			// Le port com est déjà utilisé
    e_ErrCom_Inexistant,		// Le port com n'existe pas
    e_ErrCom_Timeout,			// Timeout lors d'une émission-réception
    e_ErrCom_Emission,			// Erreur lors de l'émission
    e_ErrCom_Reception,			// Erreur lors de la réception
    e_ErrCom_Definition_Trame,  // Erreur de définition de la trame
} e_ErrCom;

// Nom du port série

// Définition des vitesses de communication
#define V1200       1200
#define V2400       2400
#define V4800       4800
#define V9600       9600

// Définition du nombre de bits
#define BITS_7  7
#define BITS_8  8

// Définition du nombre de bits de stop
#define BIT_DE_STOP_1   1
#define BIT_DE_STOP_2   2

// Définition de la parité
#define PAS_DE_PARITE   'N' //NOT OF PARITY
#define PARITE_IMPAIRE  'O' //ODD
#define PARITE_PAIRE    'E' //EVEN

// Codes de retour génériques
//#define OK 1
//#define KO 0

// Longueur max réservée pour une trame
#define LG_TRAME    1024 //1 KOctets

// PROTOTYPES
//----------------------------------------------------------------------------
e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int StopBits);
e_ErrCom EmissionCom(const void *lpBuf, unsigned int nCount);
e_ErrCom ReceptionCom(void *lpBuf, unsigned int nCountMax, unsigned int *pCountRead);
void ERROR_MSG(e_ErrCom g_ErrCom);
void ThreadReception();
DWORD WINAPI dwThreadProc(LPVOID lParam);

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

void FermeCom();

// VARIABLES GLOBALES
//-----------------------------------------------------------------------------
DCB g_DCB;                          // structure dcb du port
e_ErrCom g_ErrCom= e_ErrCom_None;   // Variable des erreurs de com
HANDLE g_hCom = 0;					// handle de la com (le fichier)
DWORD dwEvtMask = 0;				// événement qui se produit
OVERLAPPED g_ov;					// structure OVERLAPPED de Synchronisation I/O 
int g_Longueur;						// Longueur de trame
char g_Com[5];						// Les COM :COM1,COM2,COM3...
int Index;							// L'index des COM...

//******************************************************************************
//------------------------------------------------------------------------------
// FONCTION : main 
//------------------------------------------------------------------------------
// DESCRIPTION  :
// La fonction principale
//
//------------------------------------------------------------------------------
void main (void)
{
	//Declaration des variables:
	//Tableau de caractère à envoyer
	char TrameEnvoi[100]="S.O.S....";
	//Tableau de caractère reçus
	char TrameRecue[100];
	//Nombre maxi de caractère a lire(ici 100)
	unsigned int NbMaxCar=100;
	//Nombre de caractère reçus
	unsigned int NbCarRecus;

	for(Index=1;Index<=5;Index++)
	{
	sprintf(g_Com,"COM%d",Index);
    //Exemple de configuration du port serie :

    g_ErrCom=OuvreCom(g_Com,V9600,BITS_7,PAS_DE_PARITE,BIT_DE_STOP_1);
	printf("\nLes erreurs de la configuration du %s\n",g_Com);
	
	ERROR_MSG(g_ErrCom);

	g_Longueur=strlen(TrameEnvoi);
    //Exemple d'emission
    g_ErrCom=EmissionCom(&TrameEnvoi,sizeof(TrameEnvoi));
	printf("\nLes erreurs de l'envoi de la trame par le %s:\n%s \n",g_Com,TrameEnvoi);
	ERROR_MSG(g_ErrCom);
		//Test de reception avec le thread
	ThreadReception();

	}
		//Test de reception sans faire du thread
			// Exemple de reception 
				//g_ErrCom=ReceptionCom(TrameRecue,NbMaxCar,&NbCarRecus);
				//printf("Les erreurs de la reception de la trame \n%s \nd'une taille de %d caractères.\n",TrameRecue,strlen(TrameRecue));
				//ERROR_MSG(g_ErrCom);
				//getch();
}
//------------------------------------------------------------------------------
//******************************************************************************

//******************************************************************************
//------------------------------------------------------------------------------
// FONCTION : OuvreCom
//------------------------------------------------------------------------------
// DESCRIPTION  :
// Initialise et ouvre un port série
//
//------------------------------------------------------------------------------
// PARAMETRES   : 
//      - strPort       Nom du port "COM1", "COM2"
//      - BaudRate      Vitesse
//      - BitsSize      Taille de l'info
//      - Parity        Parité
//      - StopBits      Nombre de bits de stop
//
// RETOUR   :Code d'erreur
//------------------------------------------------------------------------------
e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int StopBits)
{
    g_ErrCom = e_ErrCom_None;

    // On ouvre le port série
    g_hCom = CreateFile(strPort,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,  //|  FILE_FLAG_OVERLAPPED ????
		NULL);

    if(g_hCom == INVALID_HANDLE_VALUE)
    {
        // Echec
        g_ErrCom=e_ErrCom_Creation;
    }
    else //Sinon
    {
        // On vide les buffers
        PurgeComm(g_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);      

        // On paramètre le port série
        g_DCB.DCBlength = sizeof(DCB);
        //Configuration actuelle
        GetCommState(g_hCom, &g_DCB);
        //Modification du DCB
        g_DCB.BaudRate=BaudRate;		//Vitesse
        g_DCB.ByteSize=BitsSize;		//Taille de l'info
        g_DCB.Parity=Parity;			//Parité
        g_DCB.StopBits=StopBits;		//Nombre de bits de stop
        g_DCB.fDtrControl=DTR_CONTROL_DISABLE;
        //Configuration de la liaison serie
        SetCommState(g_hCom,&g_DCB);
    }
    return g_ErrCom;
}
//----------------------------------------------------------------------------
//****************************************************************************

//****************************************************************************
//----------------------------------------------------------------------------
// FONCTION : EmissionCom
//----------------------------------------------------------------------------
// DESCRIPTION  :
// Emission d'octets sur la liaison série
//
//----------------------------------------------------------------------------
// PARAMETRES   : 
//      -lpBuf Pointeur sur les octets a emettre
//      -nCount Nombre d'octet a emettre
//
//----------------------------------------------------------------------------
// RETOUR   :Code d'erreur
//----------------------------------------------------------------------------
e_ErrCom EmissionCom(const void* lpBuf,unsigned int nCount)
{   

    DWORD NumBytes=0;

    if(g_hCom!=NULL)
    {
        // pas d'erreur
        g_ErrCom=e_ErrCom_None;

        //Emission du buffer
        if(WriteFile(g_hCom,lpBuf,nCount,&NumBytes,NULL)==0)
        {
			//Erreur lors de l'émission
            g_ErrCom=e_ErrCom_Emission;
        }
    }
    else
        //Le port n'a pas été ouvert
        g_ErrCom=e_ErrCom_Creation;

    return g_ErrCom;

}
//---------------------------------------------------------------------------
//***************************************************************************

//***************************************************************************
//---------------------------------------------------------------------------
// FONCTION : ReceptionCom
//---------------------------------------------------------------------------
// DESCRIPTION  :
// Reception de caractères sur la liaison série
//
//---------------------------------------------------------------------------
// PARAMETRES   : 
//      -lpBuf Pointeur sur le buffer de caractère a lire
//      -nCountMax Nombre maxi de caractère a lire
//      -pCountRead Pointeur sur le nombre de caractères lus
//---------------------------------------------------------------------------
// RETOUR   :Code d'erreur
//---------------------------------------------------------------------------
e_ErrCom ReceptionCom(void *lpBuf,unsigned int nCountMax, unsigned int* pCountRead)
{
COMSTAT Stat;
DWORD Errors;
unsigned int NCarALire;
unsigned long NCarLus=0;

char *t;

    if(g_hCom!=NULL)
    {
        // on pari sur pas d'erreur
        g_ErrCom=e_ErrCom_None;
		t="Traitement";
		//	Pour éviter de générer un time out

        // Pour connaitre le nombre d'octets dans le buffer d'entrée
        ClearCommError(g_hCom,&Errors,&Stat);
        NCarALire=Stat.cbInQue;

        // On effectue la lecture si il y a des caractères présents
        if( (NCarALire>0)&&(NCarALire<=nCountMax) )
        {
            if(ReadFile(g_hCom,lpBuf,NCarALire,&NCarLus,NULL)==0)
            {       
                g_ErrCom=e_ErrCom_Reception;
            }
        }
		else 
			g_ErrCom=e_ErrCom_Definition_Trame;

  • pCountRead=NCarLus;
} else // Le port n a pas été ouvert g_ErrCom=e_ErrCom_Creation; // Compte rendu de l'exécution return g_ErrCom; } //--------------------------------------------------------------------------- //*************************************************************************** //----------------------------------------------------------------------- // FONCTION : FermeCom //----------------------------------------------------------------------- // DESCRIPTION : // Ferme le port série préalablement ouvert avec OuvreCom // //----------------------------------------------------------------------- // PARAMETRES : // Néant //----------------------------------------------------------------------- // RETOUR :Néant //----------------------------------------------------------------------- void FermeCom() { if(g_hCom!=NULL) { CloseHandle(g_hCom); } } //--------------------------------------------------------------------------- //*************************************************************************** /***************************************************************************/ //--------------------------------------------------------------------------- // FONCTION : ThreadReception //----------------------------------------------------------------------- // DESCRIPTION : // Creation du thread dwThreadProc(LPVOID lParam) // //----------------------------------------------------------------------- // PARAMETRES : // Néant //----------------------------------------------------------------------- // RETOUR :Néant //----------------------------------------------------------------------- DWORD dwThread = 0; void ThreadReception() { // id de notre thread // handle de notre thread HANDLE hThread = 0; // créé notre thread en le mettant en suspend(pause) hThread = CreateThread(NULL, 0, dwThreadProc, 0, CREATE_SUSPENDED, &dwThread); // si erreur lors de la création de notre thread if ( hThread == NULL ) { printf("erreur lors de la création du thread\n"); // GetLastError() te donne le code d'erreur si tu veux le récupérer } else // sinon, tout est okay { // lancement de l'exécution de notre thread ResumeThread(hThread); // et patiente jusqu'a ce que notre thread soit fermé WaitForSingleObject(hThread,100/*INFINITE*/); } //} } //--------------------------------------------------------------------------- //*************************************************************************** //*************************************************************************** //--------------------------------------------------------------------------- // FONCTION : dwThreadProc //----------------------------------------------------------------------- // DESCRIPTION : // Identification du thread par ID // Détéction de trame :l'attent que des caractères soit arrivés... // //----------------------------------------------------------------------- // PARAMETRES : // -LPVOID lParam: 32-bit message parameter //----------------------------------------------------------------------- // RETOUR :DWORD //----------------------------------------------------------------------- DWORD WINAPI dwThreadProc(LPVOID lParam) { DWORD dwResult=0; COMSTAT Stat; DWORD Errors; //Tableau de caractère reçus char TrameRecue[100]; int Compter; //Nombre maxi de caractère a lire(ici 100) unsigned int NbMaxCar=100; //Nombre de caractère reçus unsigned int NbCarRecus; //Nombre de caractère Lus unsigned long NCarLus=0; //Nombre de caractère a lire unsigned int NCarALire=0; char *attente; printf("\nDetection de trame par %s est en cours....\n", g_Com); ZeroMemory(&g_ov, sizeof(OVERLAPPED)); printf("\n\t(*)le thread est bien cree %d\n",GetCurrentThreadId()); //Identifies an event set to the signaled state when the transfer has been completed g_ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); printf("\n\n\nLes erreurs de la reception de la trame.\n"); if(!WaitCommEvent(g_hCom, &dwEvtMask, &g_ov)) { ClearCommError(g_hCom,&Errors,&Stat); //Si Errors=0 donc Opération réussie. g_ErrCom=e_ErrCom_Creation; Compter=0; while(g_ErrCom!=e_ErrCom_None) { if (Compter>=600/*Le nombre de tentative!!!*/) { attente="\n"; g_ErrCom=e_ErrCom_Timeout; break; } else attente="."; Compter=Compter+1; printf("%s",attente); g_ErrCom=ReceptionCom(TrameRecue,NbMaxCar,&NbCarRecus); if (g_ErrCom==e_ErrCom_None) { printf("\nDetail de la reception: \n"); printf("\t------------------------------------\n"); printf("\t| Le port | %s\t\t |\n",g_Com); printf("\t------------------------------------\n"); printf("\t| ID-Thread | %d\t\t |\n",GetCurrentThreadId()); printf("\t------------------------------------\n"); printf("\t| La trame | %s\t\t |\n",TrameRecue); printf("\t------------------------------------\n"); printf("\t| La taille | %d\t\t\t |\n",strlen(TrameRecue)); printf("\t------------------------------------\n\n\n"); printf("Fermeture du port."); Sleep(50000); FermeCom(); } } } ERROR_MSG(g_ErrCom); return 0; // c'est terminé } //----------------------------------------------------------------------- //*********************************************************************** //----------------------------------------------------------------------- // FONCTION : ERROR_MSG //----------------------------------------------------------------------- // DESCRIPTION : //La liste des erreurs que le port peut subir // //----------------------------------------------------------------------- // PARAMETRES : // -Code d'erreur //----------------------------------------------------------------------- // RETOUR :Néant //----------------------------------------------------------------------- void ERROR_MSG(e_ErrCom g_ErrCom) { switch (g_ErrCom) { case e_ErrCom_None: // Pas d'erreur printf("\n\n\t\t\t\t\t%d) Pas d'erreur\n\n\n",g_ErrCom); break; case e_ErrCom_Creation: // Erreur lors de la création du flux printf("\n\t\t\t\t\t%d) Erreur lors de la création du flux\n\n\n",g_ErrCom); break; case e_ErrCom_Utilise: // Le port com est déjà utilisé printf("\n\t\t\t\t\t%d) Le port com est déjà utilisé\n\n\n",g_ErrCom); break; case e_ErrCom_Inexistant: // Le port com n'existe pas printf("\n\t\t\t\t\t%d) Le port com n'existe pas\n\n\n",g_ErrCom); break; case e_ErrCom_Timeout: // Timeout lors d'une émission-réception printf("\n\t\t\t\t\t%d) Timeout lors d'une émission-réception\n\n\n",g_ErrCom); break; case e_ErrCom_Emission: // Erreur lors de l'émission printf("\n\t\t\t\t\t%d) Erreur lors de l'émission\n\n\n",g_ErrCom); break; case e_ErrCom_Reception: // Erreur lors de la réception printf("\n\t\t\t\t\t%d) Erreur lors de la réception\n\n\n",g_ErrCom); break; case e_ErrCom_Definition_Trame: // Erreur de définition de la trame printf("\n\t\t\t\t\t%d) Erreur de définition de la trame\n\n\n",g_ErrCom); break; default: // Demande non prise en compte printf("\n\t\t\t\t\t%d) Demande non prise en compte\n\n\n",g_ErrCom); } } /* typedef struct _DCB { // dcb DWORD DCBlength; // sizeof(DCB) DWORD BaudRate; // current baud rate DWORD fBinary: 1; // binary mode, no EOF check DWORD fParity: 1; // enable parity checking DWORD fOutxCtsFlow:1; // CTS output flow control DWORD fOutxDsrFlow:1; // DSR output flow control DWORD fDtrControl:2; // DTR flow control type DWORD fDsrSensitivity:1; // DSR sensitivity DWORD fTXContinueOnXoff:1; // XOFF continues Tx DWORD fOutX: 1; // XON/XOFF out flow control DWORD fInX: 1; // XON/XOFF in flow control DWORD fErrorChar: 1; // enable error replacement DWORD fNull: 1; // enable null stripping DWORD fRtsControl:2; // RTS flow control DWORD fAbortOnError:1; // abort reads/writes on error DWORD fDummy2:17; // reserved WORD wReserved; // not currently used WORD XonLim; // transmit XON threshold WORD XoffLim; // transmit XOFF threshold BYTE ByteSize; // number of bits/byte, 4-8 BYTE Parity; // 0-4=no,odd,even,mark,space BYTE StopBits; // 0,1,2 = 1, 1.5, 2 char XonChar; // Tx and Rx XON character char XoffChar; // Tx and Rx XOFF character char ErrorChar; // error replacement character char EofChar; // end of input character char EvtChar; // received event character WORD wReserved1; // reserved; do not use } DCB;
  • /
/*The OVERLAPPED structure contains information used in asynchronous input and output (I/O). typedef struct _OVERLAPPED { // o DWORD Internal; DWORD InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent; //Identifies an event set to the signalled state when the transfer has been completed } OVERLAPPED;
  • /

Conclusion :


mon soft sera mis à jours dans x temps

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.