|
|
|||||
|
Cet article vous expliquera l'utilisation des fonctions API qui utilisent les fonctions de vos drivers de base qui vous seront utiles pour programmer une communication via les ports série que se soit pour Pocket PC ou Windows CE en général.
Pour pouvoir effectuer une communication via un port série, il faut en premier lieu pouvoir l'atteindre par l'intermédiaire de l'OS. Pour effectuer cette manœuvre, on dispose d'API permettant d'obtenir un chemin entre votre application et le port série en passant successivement les couches de l'OS et des drivers associés à la gestion des ports série. La fonction CreateFile va vous renvoyer une instance sur le chemin d'accès qui vous permettra d'utiliser votre port série. Il vous suffit seulement de lui passer en paramètre le nom du port que vous souhaitez utiliser. Cette fonction va par la suite récupérer dans la base de registre les informations correspondant au port de communication désigné tel que son adresse de base, etc … Une fois que vous possédez ce chemin d'accès, vous devez passer à l'étape suivant qui est la configuration du port série. Pour ce faire, il faut configurer le registre hardware du port via les fonctions GetCommState & SetCommState. Ces fonctions vont récupérer dans une structure les informations du registre pour ensuite les remettre modifiées selon vos désirs. Une fois ces étapes finalisées, vous pouvez commencer à dialoguer. Pour envoyer un caractère sur le port série, vous devez utiliser la fonction WriteFile. Pour Recevoir un caractère sur le port série, vous devez utiliser la fonction ReadFile. Pour mettre fin à la communication, il vous suffit de libérer le port série en libérant l'instance créée précédemment. Pour cette manœuvre utiliser la fonction CloseHandle.
Pour avoir accès au port série, il vous faut créer une instance de type HANDLE qui vous permettra via les drivers d'activer l'utilisation d'un port. Pour ce faire, vous disposez de cette fonction : HANDLE CreateFile(
LPCTSTR lpFileName, // pointer sur le nom du port à utiliser
DWORD dwDesiredAccess, // mode d'accès (read-write)
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDisposition, // Condition pour créer l'instance
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
Exemple commenté: // Déclaration de notre instance pour accueillir l'accès au port série HANDLE hPort; //Nom du port série auquel on veut accéder LPSTR lpszPortName = _T("COM1:"); // Les deux points ( : ) sont important ils indiquent à la //fonction qu'il s'agit du chemin d'une ressource de communication. //Ce chemin est connu de Windows grâce à la base de registre de l'OS //Il n'est donc pas nécessaire de connaître l'adresse de //base du port série en question //Open the serial port. hPort = CreateFile ( lpszPortName, //Pointer to the name of the port GENERIC_READ | GENERIC_WRITE, //accès en lecture ou en écriture 0, //Share mode NULL, //Pointer to the security attribute OPEN_EXISTING, //Cela indique que l'instance sera créée //à condition que le port de //communication demandé existe //et donc est connu de l'OS 0, //Port attributes NULL); //Handle to port with //attribute to copy //vérification sur la création de l'instance
if ( hPort == INVALID_HANDLE_VALUE )
{
//insérer votre code d'erreur ici
}
Pour qu'une communication entre deux appareils puisse exister, il faut qu'ils parlent le même langage. Pour ce faire, la configuration des ports série doit être identique des deux cotés. Le procédé de configuration
est simple et se passe en trois temps. Au bout de cette étape les registres de vos ports série sont prêts, vous pouvez communiquer. La structure du port série : 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;
La fonction de récupération : BOOL GetCommState( HANDLE hFile, //instance d'accès de votre port série LPDCB lpDCB //Pointeur sur votre structure de configuration ); La fonction de renvoie : BOOL SetCommState(
HANDLE hFile, // instance d'accès de votre port série
LPDCB lpDCB // Pointeur sur votre structure de configuration
);
Exemple commenté : Vous n'êtes pas obligé de mettre à jour entièrement votre structure, car elle représente une copie du registre du port série et donc ce que vous ne remplirez pas restera à son ancienne valeur ou celle par défaut. DCB PortDCB;
//Récupération des informations enregistées du port série dans votre structure.
GetCommState (hPort, // instance d'accès de votre port série
&PortDCB); // Structure de configuration
// mise à jour de la structure
PortDCB.DCBlength = sizeof (DCB);
PortDCB.BaudRate = 9600;
PortDCB.fBinary = TRUE;
PortDCB.fParity = TRUE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
//Renvoie des nouvelles informations dans le registre de votre port série
if (!SetCommState (hPort, &PortDCB))
{
//Mettre ici votre code d'erreur
}
Pour ce faire, utiliser cette fonction : BOOL WriteFile(
HANDLE hFile, //Instance de votre accès au port série
LPCVOID lpBuffer, //Pointeur sur la donnée à écrire
DWORD nNumberOfBytesToWrite, //Nombre de bytes à écrire
LPDWORD lpNumberOfBytesWritten, //pointeur to number of bytes written
LPOVERLAPPED lpOverlapped //Doit être NULL pour windows CE
);
Exemple commenté : DWORD dwNumBytesWritten;
BYTE Byte = 'a';
if (!WriteFile (hPort, // Instance d'accès de votre port série
&Byte, //Pointeur sur la donnée à envoyer
1, //Nombre de byte à envoyer
&dwNumBytesWritten, //Pointer sur la variable contenant le nombre
//byte écrit dans le buffer
NULL)) //Doit être NULL pour Windows CE
{
//code d'erreur
}
Le port série peut recevoir différents types d'événements comme l'arrivée d'une donnée, buffer d'envoie vide ou différents signaux (CTS, DSR) ce qui permet une large manipulation de ceux-ci Ici seul l'arrivée d'une donnée nous intéresse. Exemple commenté : BYTE Byte;
DWORD dwCommStatus, // variable de stockage pour les évènements
DWORD dwBytesTransferred;
//Cette fonction définit les évènements pour lesquels
//ont va réagir par rapport à notre instance
SetCommMask (hPort,
EV_RXCHAR ); //ici EV_RXCHAR indique que l'on va détecter la réception
//de données (cette entrée est de type DWORD)
//Cette fonction est bloquante, elle va attendre //des événements définit par le mask et //Elle stockera le type d'événement qui l'aura réveillée dans une variable. WaitCommEvent (hPort, //instance d'accès du port série &dwCommStatus, //Pointeur sur la variable de stockage pour les évènements //Cette entrée est de type LPDWORD 0); //pointeur sur la structure d'overlapped. //Ici il n'y en a pas. //cette entrée est de type LPOVERLAPPED //Cette fonction permet la lecture du buffer d'entrée du port série ReadFile (hPort, //Instance sur l'accès du port série &Byte, //Conteneur pour récupérer le byte lu 1, //Nombre de byte à lire &dwBytesTransferred, //Pointer sur le nombre de byte lu, sert à //la gestion propre de la fonction read. 0); //Doit être NULL pour Windows CE // Permet l'affichage de votre conteneur Printf("%c",Byte);
Pour ce faire, utilisez cette fonction : BOOL CloseHandle( HANDLE hObject //Instance d'accès du port série ); |
|||||
|
|
|||||
|
Copyright 2001-2004 - Tous droits réservés
|
|||||
|
iPAQ
est un produit de COMPAQ.
|