Communication RS232 : Pb de vitesse

cs_arb Messages postés 40 Date d'inscription lundi 18 février 2002 Statut Membre Dernière intervention 5 novembre 2012 - 27 sept. 2006 à 18:23
Moucave Messages postés 130 Date d'inscription mardi 21 novembre 2000 Statut Membre Dernière intervention 10 septembre 2008 - 3 oct. 2006 à 17:28
Bonjour


Je me suis insipiré du code de ymca2003 (Code source N°22441) pour faire un petit programme qui envoie le contenu d'un fichier via une liaison RS232 à une carte externe. J'ai la même appli qui tourne bien en Visual Basic, et j'ai un souci de vitesse maintenant. Avec le code de YMCA2003, tout va bien pour des vitesses allant jusqu'à 57600 par contre à 115200 ça ne marche plus. Quelqu'un aurait il une idée ou des pistes? j'utilise devcpp, je joins mon code. D'avance merci.
La lecture de mon fichier et l'envoi des trames est correct jusqu'à 57600. Un problème avec les constantes de timeout pour lecture ou ecriture?


merci de votre aide




#define RX_SIZE         4096    /* taille tampon d'entrée  */
#define TX_SIZE         4096    /* taille tampon de sortie */
#define MAX_WAIT_READ   5000    /* temps max d'attente pour lecture (en ms) */


// ---------------- INCLUDE SECTION -----------------------------
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>


// ----------------- VISIBILITY SECTION -------------------------
BOOL OpenCOM    (int nId);
BOOL CloseCOM   ();
BOOL ReadCOM    (void* buffer, int nBytesToRead, int* pBytesRead);
BOOL WriteCOM   (void* buffer, int nBytesToWrite, int* pBytesWritten);
void SendFile   (void);


// ----------------- DATA SECTION -------------------------------
// Handle du port COM ouvert
HANDLE g_hCOM = NULL;


//Délais d'attente sur le port COM
COMMTIMEOUTS g_cto =
{
    MAX_WAIT_READ,  // ReadIntervalTimeOut        
    0,              // ReadTotalTimeOutMultiplier  
    MAX_WAIT_READ,  // ReadTotalTimeOutConstant    
    0,              // WriteTotalTimeOutMultiplier 
    0               // WriteTotalTimeOutConstant   
};


// Configuration du port COM
DCB g_dcb =
{
    sizeof(DCB),        // DCBlength
    0,                  // BaudRate
    TRUE,               // fBinary
    FALSE,              // fParity
    FALSE,              // fOutxCtsFlow
    FALSE,              // fOutxDsrFlow
    DTR_CONTROL_DISABLE, // fDtrControl
    FALSE,              // fDsrSensitivity
    FALSE,              // fTXContinueOnXoff
    FALSE,              // fOutX
    FALSE,              // fInX
    FALSE,              // fErrorChar
    FALSE,              // fNull
    RTS_CONTROL_DISABLE, // fRtsControl
    FALSE,              // fAbortOnError
    0,                  // fDummy2
    0,                  // wReserved
    0x100,              // XonLim
    0x100,              // XoffLim
    8,                  // ByteSize
    NOPARITY,           // Parity
    ONESTOPBIT,         // StopBits
    0x11,               // XonChar
    0x13,               // XoffChar
    '?',                // ErrorChar
    0x1A,               // EofChar
    0x10                // EvtChar
};


int main()
{
    // variables locales
    unsigned char buf_rx[8];
    unsigned char buf_tx[8];
    int nId, nBytesWritten, nBytesRead;
    unsigned char vitesse;     // Choix vitesse
   
    printf("\n");
    // demande du numéro du port COM
    printf("Entrez le numero du port COM : ");
    scanf("%d", &nId);
    // choix de la vitesse           
    printf("\n");
    printf("Choisissez la vitesse 19200, 38400, 57600 en tapant  1, 2 ou 3 : ");    scanf("%d", &vitesse);
    //Gestion vitesse
    switch (vitesse)
  {
  case 1:
   g_dcb.BaudRate= 19200;
   break;       
  case 2:
   g_dcb.BaudRate= 38400;
   break;
  case 3:
   g_dcb.BaudRate= 57600;
   break;
  default:
   printf("\n"); 
   printf("Choix de la vitesse impossible - Fin du programme\r\n");
   printf("Taper sur n'importe quelle touche pour sortir.\r\n");
   getch();
   return -1;
  }
   
    // fichier à telecharger
    printf("\n");
    printf("Entrez le nom du fichier telecharger : ");
    scanf("%s", &name);
   
    //SendFile();
    // OUverture du fichier pour être sûr de sa validité dès maintenant
   
    fichier_ldr = fopen(name, "rb");
    if (fichier_ldr == NULL)
       {
       printf("\n");
       printf("Impossible d'ouvrir le fichier %s  - Fin du programme.\r\n",name);
       printf("Taper sur n'importe quelle touche pour sortir.\r\n");
       getch();
       return -1;
       }
    else
        printf("Fichier %s ouvert avec succes.\r\n\n", name);
     
    // tentative d'ouverture du port COM
    printf("\n");
    printf("Ouverture et configuration du port COM%d en cours ......\r\n", nId);
    if(!OpenCOM(nId))
  {
  printf("Taper sur n'importe quelle touche pour sortir.\r\n");
  getch();
  return -1;
  }
    printf("...OK\r\n\n");
   
    SendFile();
   
   // fermeture du port COM et retour
    CloseCOM();
    // attendre l'appui d'une touche pour fermer l'appli
    getch();
 return 0;
}


/******************************************************************************
  OpenCOM : ouverture et configuration du port COM.
  entrée  : nId : Id du port COM à ouvrir.
  retour  : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL OpenCOM(int nId)
{
    // variables locales
    char szCOM[16];


    // construction du nom du port, tentative d'ouverture
    sprintf(szCOM, "COM%d", nId);
    g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    if(g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d   - Fin du programme.\r\n", nId);
        return FALSE;
    }


    // affectation taille des tampons d'émission et de réception
    SetupComm(g_hCOM, RX_SIZE, TX_SIZE);


    // configuration du port COM
    if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d   - Fin du programme.\r\n", nId);
        CloseHandle(g_hCOM);
        return FALSE;
    }


    // on vide les tampons d'émission et de réception, mise à 1 DTR
    PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(g_hCOM, SETDTR);
    return TRUE;
}


/******************************************************************************
  CloseCOM : fermeture du port COM.
  retour   : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL CloseCOM()
{
    // fermeture du port COM
    CloseHandle(g_hCOM);
    return TRUE;
}


/******************************************************************************
  ReadCOM : lecture de données sur le port COM.
  entrée  : buffer       : buffer où mettre les données lues.
          : nBytesToRead : nombre max d'octets à lire.
          :  pBytesRead   : variable qui va recevoir le nombre d'octets lus.
  retour  : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
  Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
              - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    return ReadFile(g_hCOM, buffer, nBytesToRead, (DWORD*)pBytesRead, NULL);
}


/******************************************************************************
  WriteCOM : envoi de données sur le port COM.
  entrée   : buffer        : buffer avec les données à envoyer.
           : nBytesToWrite : nombre d'octets à envoyer.
           : pBytesWritten : variable qui va recevoir le nombre d'octets
        envoyés.
  retour   : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    // écriture sur le port
    return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);
}

2 réponses

olbal Messages postés 20 Date d'inscription vendredi 16 mai 2003 Statut Membre Dernière intervention 29 septembre 2006
29 sept. 2006 à 13:21
Je pense que c'est un problème de controle de flux. Les données arrive plus vite que la carte ne peut les traiter. Active le controle de flux par RTS/CTS si c'est possible ou controle l'émission du flux de manière logiciel XON/XOFF par ex. En VB ça marchait peut-être à cause de la lenteur de ce langage, qui provoquait des pauses en chaque octets envoyés.
0
Moucave Messages postés 130 Date d'inscription mardi 21 novembre 2000 Statut Membre Dernière intervention 10 septembre 2008
3 oct. 2006 à 17:28
Slt, je pense aussi que ton problème vient en effet d'un problème de control de flux. Sans contrôle de flux il se peut qu'il se produisse un glissement d'horloge entre celle cadençant l'envoi des donnée (pc) et celle réceptionnant tes données (carte). En gros ta carte décroche . Je ne vois pas quelle correction tu pourais apporter en C++ sinon réduite la vitesse de transmission.


@++

--- Moucave , petit singe au pays du c++  ---
0
Rejoignez-nous