Transmission de fichier par le port série

Signaler
Messages postés
23
Date d'inscription
lundi 9 février 2004
Statut
Membre
Dernière intervention
18 janvier 2005
-
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
-
Salur à vous
Je voudrais savoir si c'est assez facile de réceptionner un fichier par l'intermédiare du port série et si oui, si quelqu'un peut me proposer quelque chose.
de plus je vais certainement devoir créer une tâche de fond sous Windows 95, ma question est donc de savoir si c'est possible.

Mecri pour votre aide.
@++

7 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
voici une version épurée de mon prog serial qui ne fait que la réception (tous les paramètres sont en dur, pas de vérif d'erreurs). bouton recevoir débute la réception Stop l'arrête

Recep.cpp :

#include <windows.h>

#include "Resource.h"

// message rensignant sur le nb d'octets reçus
#define WM_COMM_RX(WM_USER + 0x100)

// variables globales
HINSTANCE g_hAppInstance = NULL; // instance de l'application
HWND g_hMainDlg = NULL; // boîte de dialogue
HANDLE g_hComm = NULL; // handle port série
HANDLE g_hThread = NULL; // handle thread de lecture
BOOL g_bRunning = FALSE; // vrai si thread doit continuer

int CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);

void CmdRecep();
void CmdStop();

DWORD WINAPI ThreadFunc(LPVOID);

//************************************************
//************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  LPSTR lpCmdLine, int nCmdShow)
{
  g_hAppInstance = hInstance;
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, DlgProc);
  return 0;
}

//************************************************
//************************************************
int CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch(uMsg)
  {
    case WM_INITDIALOG :
    {
      g_hMainDlg = hDlg;
      EnableWindow(GetDlgItem(hDlg, IDC_RECEP), TRUE);
      EnableWindow(GetDlgItem(hDlg, IDC_STOP), FALSE);
      return TRUE;
    }
    case WM_COMMAND :
    {
      switch(LOWORD(wParam))
      {
        case IDCANCEL : CmdStop(); EndDialog(hDlg, IDCANCEL); return TRUE;
        case IDOK : CmdStop(); EndDialog(hDlg, IDOK); return TRUE;
        case IDC_RECEP	: CmdRecep(); return TRUE;
        case IDC_STOP	: CmdStop(); return TRUE;
      }
      return FALSE;
}
    case WM_COMM_RX :
    {
      // mise à jour nombre d'octets reçu
      char szText[64];
      wsprintf(szText, "%d octets", lParam);
      SetWindowText(GetDlgItem(hDlg, IDC_NB), szText);
    }
  }
  return 0;
}

//************************************************
//************************************************
void CmdRecep()
{
  // ouverture port série
  g_hComm = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
  SetupComm(g_hComm, 4096, 4096);

  // affectation délais
  COMMTIMEOUTS cto;
  ZeroMemory(&cto, sizeof(COMMTIMEOUTS));
  cto.ReadIntervalTimeout = 0xFFFFFFFF;
  SetCommTimeouts(g_hComm, &cto);

  // affectation configuration
  DCB dcb;
  ZeroMemory(&dcb, sizeof(DCB));
  dcb.DCBlength = sizeof(DCB);
  dcb.BaudRate = 9600;
  dcb.fBinary = TRUE;
  dcb.fDtrControl = DTR_CONTROL_ENABLE;
  dcb.fRtsControl = RTS_CONTROL_ENABLE;
  dcb.XonLim = 0x100;
  dcb.XoffLim = 0x100;
  dcb.ByteSize = 8;
  dcb.Parity = NOPARITY;
  dcb.StopBits = ONESTOPBIT;
  dcb.XonChar = 0x11;
  dcb.XonChar = 0x13;
  dcb.ErrorChar = '?';
  dcb.EofChar = 0x1A;
  dcb.EvtChar = 0x10;
  SetCommState(g_hComm, &dcb);
  
  // purge
  PurgeComm(g_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
  EscapeCommFunction(g_hComm, SETDTR);

  // création thread de lecture
  DWORD dwThreadId;
  g_bRunning = TRUE;
  g_hThread = CreateThread(NULL, 0, ThreadFunc, &g_bRunning, 0, &dwThreadId);

  // mise à jour affichage
  EnableWindow(GetDlgItem(g_hMainDlg, IDC_RECEP), FALSE);
  EnableWindow(GetDlgItem(g_hMainDlg, IDC_STOP), TRUE);
  SetWindowText(GetDlgItem(g_hMainDlg, IDC_NB), "");
}

//************************************************
//************************************************
void CmdStop()
{
  // si pas de thread en cours
  if(g_hThread == NULL)
    return;

  // on attend que le thread s'arrête tout en traitant les messages
  // relatifs au port série
  g_bRunning = FALSE;
  while(WaitForSingleObject(g_hThread, 10) != WAIT_OBJECT_0)
  {
    // si un message relatif au port série est présent
    MSG msg;
    if(PeekMessage(&msg, NULL, WM_COMM_RX, WM_COMM_RX, PM_REMOVE))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  // fermeture handles
  CloseHandle(g_hThread);
  CloseHandle(g_hComm);
  g_hThread = NULL;
  g_hComm = NULL;
  EnableWindow(GetDlgItem(g_hMainDlg, IDC_RECEP), TRUE);
  EnableWindow(GetDlgItem(g_hMainDlg, IDC_STOP), FALSE);
}

//************************************************
//************************************************
DWORD WINAPI ThreadFunc(LPVOID lpData)
{
  // ouverture fichier de sortie, récup paramètres
  HANDLE hFile = CreateFile("c:\\recep.txt", GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, 0, NULL);
  BOOL* pRunning = (BOOL*) lpData;

  BYTE buffer[4096];
  DWORD dwTotal = 0;

  // tant que le thread doit tourner
  while(*pRunning == TRUE)
  {
    // lecture d'un bloc
    DWORD dwLength;
    ReadFile(g_hComm, buffer, 4096, &dwLength, NULL);
    
    // si pas de caractères reçus, faire une petite pause
    if(dwLength == 0)
      Sleep(10);
    else
    {
      // écriture dans le fichier, notification dialogue
      DWORD dwNbBytesWritten;
      WriteFile(hFile, buffer, dwLength, &dwNbBytesWritten, NULL);
      dwTotal += dwNbBytesWritten;
      SendMessage(g_hMainDlg, WM_COMM_RX, 0, dwTotal);
    }
  }

  // fermeture fichier de sortie
  CloseHandle(hFile);
  return 0;
}


Recep.rc :

#include "Resource.h"
IDD_MAINDIALOG DIALOG DISCARDABLE  0, 0, 142, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Réception port série"
FONT 8, "MS Sans Serif"
BEGIN
    PUSHBUTTON      "Fermer",IDCANCEL,10,70,50,14
    PUSHBUTTON      "Recevoir",IDC_RECEP,10,20,50,14
    PUSHBUTTON      "Stop !",IDC_STOP,70,20,50,14
    LTEXT           "",IDC_NB,10,44,110,8
END



Resource.h :

#define IDD_MAINDIALOG                  101
#define IDC_RECEP                       1000
#define IDC_STOP                        1002
#define IDC_NB                          1003

Messages postés
23
Date d'inscription
lundi 9 février 2004
Statut
Membre
Dernière intervention
18 janvier 2005

Est ce possible de mettre ce genre de programme en tache de fond?
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
il l'est déjà plus ou moins, il suffit de virer l'interface graphique et la réception se fait par le thread créé.
Messages postés
23
Date d'inscription
lundi 9 février 2004
Statut
Membre
Dernière intervention
18 janvier 2005

j'ai essayé de suivre le raisonnement de ton programme, mais je il est un peu compliqué par rapport à mon niveau de C.
Je ne suis pas sur de savoir où est stocké le fichier reçu ( je pense que c'est dans hFile) et je n'arrive pas à différencier complètement l'interface windows du reste du programme.
Donc j'espère que tu as un peu de temps afin de me le détaillé un peu plus
Merci d'avance.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
L'interface windows et contenu dans la fonction DlgProc (gestion clique des boutons et affichage progression).

ThreadFunc est le point d'entrée du thread créé (la tache de fond), qui scrute en permannece le port série. L'appel à la fct SendMessage permet de demander d'afficher la progression.

CmdRecep et CmdStop sont 2 fonctions qui permetent de commencer et d'arrêtrer cette tache (peuvent être appelée indépendant de l'interface graphique à partir d'un prog en mode console par ex)
Messages postés
23
Date d'inscription
lundi 9 février 2004
Statut
Membre
Dernière intervention
18 janvier 2005

Bon j'ai réétudié mon problème, et je viens de voir que je ne pose pas les bonnes question.
Les commandes que tu me donnes ne sont pas compatibles avec mon soft car je suis sous DOS (Turbo C++ v3.0 càd du borland)
Donc si quelqu'un à quelque chose à me proposer je suis preneur...
Merci
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
En effet ce que je t'ai mis c'est pour Windows (API Win32).
Pour DOS, je ne sais pas comment faire.