Site : tvaira.free.fr

Mise en oeuvre d’un périphérique USB sous Windows

Tests

Programmation en C

// Lit une trame NMEA 183 sur le port série virtuel
// Version Windows

// Attention : vérifiez le nom du fichier de périphérique et la configuration du port série

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

// On fixe la taille maximum à 128 octets
#define MAX 128

//#define DEBUG

int main(void)
{
    HANDLE hPort = INVALID_HANDLE_VALUE; // Handle sur le port série
    DCB old_dcb; // anciens parametres du port série
    DCB dcb; // parametres du port série
    COMMTIMEOUTS comout = {0}; // timeout du port série
    COMMTIMEOUTS oldTimeouts; // ancien timeout du port série
    char nomPeripherique[16] = "COM3"; // nom du port série
    char* buffer = (char *)NULL; // un buffer
    char c = 0; // un caractère
    int fini = 0; // fin de reception d'une trame
    int i = 0;
    DWORD n = 0;
    BOOL succes;
    int debutTrame = 0; // debut de reception d'une trame

    /* Ouverture de la liaison serie */
    hPort = CreateFile( "COM3",
                        GENERIC_READ | GENERIC_WRITE,
                        0,
                        0,
                        OPEN_EXISTING,
                        0,
                        0);

    if( hPort == INVALID_HANDLE_VALUE )
    {
        printf("Erreur d'ouverture du peripherique COM1 !\n"); // message d'erreur client
        exit(1);
    }
    //printf("Peripherique ouvert avec succes !\n");

    /* Lecture des parametres courants  */
    GetCommState(hPort, &dcb);
    old_dcb = dcb; // sauvegarde l'ancienne configuration

    /* Liaison a 9600 bps, 8 bits de donnees, pas de parite, lecture possible */
    dcb.BaudRate = CBR_9600;
    dcb.ByteSize = 8;
    dcb.StopBits = ONESTOPBIT;
    dcb.Parity = NOPARITY;
    dcb.fBinary = TRUE;
    /* pas de control de flux */
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = FALSE;

    /* Sauvegarde des nouveaux parametres */
    if( !SetCommState(hPort, &dcb) )
    {
      printf("Impossible de configurer le port COM1 !");
      CloseHandle(hPort);
      exit(1);
    }
    SetupComm(hPort, 2048, 1024);
    GetCommTimeouts(hPort, &oldTimeouts);
    SetCommTimeouts(hPort, &comout);
    //printf("Sauvegarde de la nouvelle configuration avec succes !\n");

    /* Lecture de MAX octets */
    buffer = (char *)malloc((MAX+1) * sizeof(char)); // on alloue un buffer
    i = 0;
    debutTrame = 0;
    do
    {
        succes = ReadFile(hPort, &c, 1, &n, NULL);
        if(!succes)
        {
            printf("erreur : %d\n", GetLastError()); // cf. FormatMessage
            //break;
        }
        #ifdef DEBUG
        printf("read : %d -> 0x%02X ", n, (unsigned char)c);
        #endif
        // est-ce qu'on a lu 1 caractère ?
        if(n == 1)
        {
            // est-ce le début d'une trame ?
            if(c == '$')
            {
              debutTrame = 1;
            }
            // est-ce qu'on est entrain de lire une trame ?
            if(debutTrame == 1)
            {
              // on copie le caractère lu dans le buffer
              *(buffer + i) = c;
              i++;
            }
            // est-ce que c'est la fin de la trame qu'on est entrain de lire ?
            if (debutTrame == 1 && c == '\n')
            {
              fini = 1;
              debutTrame = 0;
            }
        }
        /*else
        {
            if(n == -1)
            {
                printf("Erreur de lecture\n"); // message client
                //fini = 1;
            }
            else
            {
                printf("Aucune lecture !\n"); // message warning
            }
        }*/
    }
    while(i <= MAX && fini == 0);

    *(buffer + i) = 0x00; // fin de chaîne (attention à i > MAX !)

    printf("Trame lue :\n%s\n", buffer);

    /* Restaure les anciens parametres du port série */
    SetCommState(hPort, &old_dcb);
    SetCommTimeouts(hPort, &oldTimeouts);
    /* Fermeture du port série */
    CloseHandle(hPort);
    //printf("Fermeture du peripherique avec succes !\n");

    free(buffer); // on libère la mémoire allouée

    return 0;
}

Vous pouvez compiler ce programme avec GCC (MinGW) ou à partir d’un EDI (DevCpp, Code::Blocks, …).

C:\> a.exe
Trame lue :
$GPZDA,001448.799,06,01,1980,,.0000,E,0,00,0,00,,,M,,,,0000*01

Retour au sommaire