Programme en C gérant les liaisons RS232

cs_proj Messages postés 5 Date d'inscription mardi 21 mars 2006 Statut Membre Dernière intervention 31 mars 2006 - 22 mars 2006 à 13:38
cs_siskozed Messages postés 11 Date d'inscription jeudi 25 janvier 2007 Statut Membre Dernière intervention 20 mars 2009 - 11 mars 2008 à 15:34
Bonjour Tout le monde,

Je suis pas une as en programmation et il m'est demandé dans le cadre de mes études de réaliser un programme en C gérant la liaison sur un PC sous Windows.
Je vous remercie d'avance pour votre aide.

9 réponses

cs_max12 Messages postés 1491 Date d'inscription dimanche 19 novembre 2000 Statut Modérateur Dernière intervention 7 juillet 2014
22 mars 2006 à 16:53
Liste des API nécéssaires :

CreateFile("COM1", ...)
ReadFile, WriteFile
CloseHandle
SetCommTimeOuts
GetCommTimeOuts
GetCommState
SetCommState

Ensuite communiquer avec un port COm c'est pareil à la manipulation des fichiers, sauf pour le state et le timeout.

A+
0
Tekila48 Messages postés 15 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 26 mars 2006
22 mars 2006 à 17:00
Il faut utiliser les structures :
COMMTIMEOUTS
DCB
et les fonctions :
CreateFile
WriteFile
ReadFile
SetCommTimeouts
SetCommState

Un port COM, c'est comme un fichier sauf que la sortie est redirigée.

Par exemple, l'ouverture se fait comme ça :

HANDLE g_hCOM;
g_hCOM = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(g_hCOM != NULL) printf("Port COM ouvert");

Avec l'aide MSDN --> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/configuring_a_communications_resource.asp) , tu devrais t'en sortir.

Sinon, envoie moi ton adresse e-mail à tekila48@yahoo.fr et je te ferais suivre du code que je compte mettre ici après quelques améliorations.
0
chooloveloo Messages postés 3 Date d'inscription dimanche 18 décembre 2005 Statut Membre Dernière intervention 14 mai 2006
22 mars 2006 à 21:23
Je suis en BTS IRIS et mon projet consiste à dialoguer avec une station météo via la liaison serie RS232.
Je pense que ceci devrais t'aider :).

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "CRS232.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
//******************************************************************************
// Constructeur : initialisation des paramètres.
//******************************************************************************
CRS232::CRS232()
{

hPort = NULL;
}

//******************************************************************************
// Destructeur: fermeture du port serie
//******************************************************************************
CRS232::~CRS232()
{
CloseHandle(hPort);
}

//******************************************************************************
// ConfigurerLiaison: configuration du port serie
//******************************************************************************
bool CRS232::ConfigurerLiaison(char* Port)
{
bool fSuccess;
DWORD Error;

// Ouverture du port de Com
hPort = CreateFile (Port,GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);

// Vérifier si handle ouvert correctement
fSuccess = hPort;
if (!fSuccess)
{
Error = GetLastError();
CloseHandle(hPort);
}
else
{

// Lecture Configuration initiale
fSuccess = GetCommState(hPort, &PortDCB);
if (!fSuccess)
{
CloseHandle(hPort);
}
else
{

// Configuration du port série
PortDCB.DCBlength = sizeof (DCB);
PortDCB.BaudRate = 9600;
PortDCB.fBinary = TRUE;
PortDCB.fParity = TRUE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;

// Ecriture Configuration initiale
fSuccess = SetCommState(hPort, &PortDCB);
if (!fSuccess)
{
CloseHandle(hPort);
}
}
}

return fSuccess;
}

//******************************************************************************
// RecevoirTrames : lecture de données sur le port série.
//******************************************************************************
void CRS232::RecevoirTrames(int nb, unsigned char *Trame)
{
DWORD nbread;
ReadFile(hPort, Trame, nb, &nbread, NULL);
}
0
cs_proj Messages postés 5 Date d'inscription mardi 21 mars 2006 Statut Membre Dernière intervention 31 mars 2006
23 mars 2006 à 18:10
Hi

j'ai bien reçu vos propositions, merci.
Surtout ne rigolez mais où est ce que je dois rentrer le programmer pour faire communiquer les ports de mes pCs entre eux.

En passant , à quoi renvoi les paramètres GENERIC_READ | GENERIC_WRITE et comment sont ils utilisés.

Je suis bien allée sur ce site mais j'ai très bien à quoi correspondait les paramètres de la fonction main du programme ( int agrc et char *argv )
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/configuring_a_communications_resource.asp

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

int main(int argc, char *argv[])
{
DCB dcb;
HANDLE hCom;
BOOL fSuccess;
char *pcCommPort = "COM2";

hCom = CreateFile( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);

if (hCom == INVALID_HANDLE_VALUE)
{
// Handle the error.
printf ("CreateFile failed with error %d.\n", GetLastError());
return (1);
}

// Build on the current configuration, and skip setting the size
// of the input and output buffers with SetupComm.

fSuccess = GetCommState(hCom, &dcb);

if (!fSuccess)
{
// Handle the error.
printf ("GetCommState failed with error %d.\n", GetLastError());
return (2);
}

// Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

dcb.BaudRate = CBR_57600; // set the baud rate
dcb.ByteSize = 8; // data size, xmit, and rcv
dcb.Parity = NOPARITY; // no parity bit
dcb.StopBits = ONESTOPBIT; // one stop bit

fSuccess = SetCommState(hCom, &dcb);

if (!fSuccess)
{
// Handle the error.
printf ("SetCommState failed with error %d.\n", GetLastError());
return (3);
}

printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
return (0);
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Tekila48 Messages postés 15 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 26 mars 2006
24 mars 2006 à 19:56
GENERIC_READ et GENERIC_WRITE servent à te donner les droits standard en lecture et en écriture

argc et argv servent à récuperer les paramètres de la ligne de commande
si tu tapes en ligne de commande : prog.exe -t c:\test.txt *.bin
tu auras dans argc le nombre de paramètres et dans argv les paramètres eux-mêmes :
argv[0] = "-t"
argv[1] = "c:\\test.txt"
argv[2] = "*.bin"
Dans ton cas, je doute que tu aies besoin de t'en servie, à moins que tu veuilles passer le numero du port à partir de la ligne de commande.

Pour faire communiquer tes deux PC, le plus simple est d'appeller les fonctions dans main, qui est le point d'entrée de ton programme.
Ex (désolé, le html marche pas chez moi, donc c'est du texte sans frioritures):

-------------------------------------------------------------------------------

#include "com_port.h" //contient les fonctions de ports COM
#include ... (inclure les en-tetes necessaires)

int main(int argc, char *argv)
{
char Buffer[256]; //buffer contenant le texte
short Run = 1; //continuer à tourner ou quitter
unsigned long* pnId = new unsigned long; //numero du port com
unsigned long* pBytesRead = new unsigned long; //nombre de bytes lus
unsigned short i; //index de caractère

C_COM_PORT* Port = new C_COM_PORT; //Créer un nouvel objet COM_PORT (défini dans com_port.h)

printf("\r\n Port COM to open : "); //Demander le numéro du port COM à ouvrir
scanf("%d", pnId);

if(!Port->OpenCOM(*pnId, 9600, 100)) return(GetLastError()); //Vérifier l'ouverture

printf("Port %s open\r\n", Port->GetPortName());

while(Run)
{
//Si l'utilisateur tapes sur une touche, récuperer toutes les touches jusqu'à l'appui de ENTREE ( \r )
i 0; //Index de caractères 0
if(kbhit())
{
printf("\r\n%s >> ", Port->GetPortName()); //Affiche >> pour signaler à l'utilisateur qu'il peut taper son texte
while((Buffer[i] = getch()) != '\r') //Tant que la touche n'est pas ENTREE
{
if(Buffer[i] == 0x8) //si backspace effacer le car precedent
{
putch(0x20); //mettre un espace pour enlever le caractère
putch(0x8); //revenir sur l'espace pour le modifier
i--; //décrémenter l'index de caractère
}
else i++; //si différent de backspace, incrémenter l'index de caractère
} //END WHILE : l'utilisateur a tapé ENTREE, envoyer le message :
printf("\r\n"); //Afficher le retour chariot
Buffer[i] = '\0'; //Fermer la chaine
if(!strcmp(Buffer, "exit")) Run = 0; //si le texte est "exit", quitter le programme
}

//Envoi du message :
strcat(Buffer, "\r\n"); //ajouter \r\n (la plupart des appareils RS232 attendent \r\n à la fin d'un message
Port->WriteCOM(Buffer); //Ecrire buffer sur le port
strcpy(Buffer, ""); //Effacer buffer

//Test de lecture : si de caractères sont detectés sur le port :
if(Port->ReadCOM(Buffer, 256, pBytesRead))
printf("%s\r\n", Buffer); //Afficher le buffer
}

delete Port; //Liberer la memoire
delete pBytesRead; //idem
delete pnId; //idem

return(0); //quitter sans erreurs
}
-------------------------------------------------------------------------------
Comme tu peux le voir, je n'utilise pas les paramètres d'entrée.

Ce week-end, je me motive et je mets tout le code
0
cs_proj Messages postés 5 Date d'inscription mardi 21 mars 2006 Statut Membre Dernière intervention 31 mars 2006
27 mars 2006 à 16:19
Bonjour TEKILA48

j'ai testé ton programme sur Borland C++ mais le compilateur ne reconnait la librairie "com_port.h".
Apparemment c'est un fichier que tu as surement créer.
Est ce que tu pourrais me l'envoyer STP.
0
Tekila48 Messages postés 15 Date d'inscription mardi 21 janvier 2003 Statut Membre Dernière intervention 26 mars 2006
31 mars 2006 à 00:18
oui, si tu me donnes ton mail, sans pb
0
cs_proj Messages postés 5 Date d'inscription mardi 21 mars 2006 Statut Membre Dernière intervention 31 mars 2006
31 mars 2006 à 08:29
voici mon mail:

ngkcindy@gmail.fr
0
cs_siskozed Messages postés 11 Date d'inscription jeudi 25 janvier 2007 Statut Membre Dernière intervention 20 mars 2009
11 mars 2008 à 15:34
je suis trop paumé... ma station météo "oregon WM928NX professional" connectée à l'hyperterminal en 9600 8 N 1 par lisaison série m'envoie n'importe quoi...
Je vois des trames mais ce n'est pas de l'héxa mais des coeurs, des piques, des têtes de bonhommes des fleches... bref de la merde.

Ma station météo sera plus tard reliée par RS232 à une carte SC13 DK51 puis le modufle sera lui relié par RJ45 au pc. Ensuite affichage dans l'ihm puis enregistrement toutes les 5 minutes des mesures.

Alors j'ai plusieurs problemes :
Je ne connais pas la trame envoyée
Je ne sais pas comment récupérer la trame (programme fossil ? je n'y comprend rien à toutes ces librairies clib.h, fossil.h etC...)
Je ne sais pas comment envoyer la trame dans le programme général (par socket surement).
0
Rejoignez-nous