Gestion RS232 sous Visual C++

Signaler
Messages postés
4
Date d'inscription
mercredi 10 mars 2004
Statut
Membre
Dernière intervention
7 juin 2004
-
Messages postés
1
Date d'inscription
samedi 4 décembre 2004
Statut
Membre
Dernière intervention
23 décembre 2004
-
Bonjour a tous.

En cours d'apprentissage et de réalisation de projet , je dois réaliser une boite de dialogue permettant de récuperer et envoyer des infos via une liaisin rs232.
Pouvez-vous m'eclairer sur les points suivants sachant que la com avec la liaison serie se fait par createfile , readfile et write file et tout une ribembelle de parametres.
-Mon point bloquant se situe essentiellemlent au niveau de la lecture car comment procede t-on pour savoir en continue si des infos sont transimes par le port.
Doit-on réaliser un thread par la commande create thread si oui comment.
D'avance Merci de votre contribution.

9 réponses

Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
le plus simple c'est de créer un timer qui fait une lecture régulière en prenent ce qui se trouve sur le port (en ajustant les paramètres de COMMTIMEOUTS avec SetCommTimeOuts:
cto = {0xFFFFFFFF, 0, 0, 0, 0};
avec ces paramètres, ReadFile retourne immédiatement s'il n'y a rien sur le port.

base sur RS232 :
http://www.cppfrance.com/code.aspx?ID=22441

programme + complet avec transmission/réceptions de fichiers, thread synchronisation et utilisation du flag overlaped
http://www.cppfrance.com/code.aspx?ID=18704
Messages postés
4
Date d'inscription
mercredi 10 mars 2004
Statut
Membre
Dernière intervention
7 juin 2004

Merci bien pour renseinements ymca2003

cependant mon soucis n'est pas de sortir de readfile s'il n'y a rien sur le port, mais bien d'effectuer une scrutation en continu pour observer l'arrivée d'éventuelle trames (une sorte de while(1) sur la fonction readfile).
C'est pour cela que j'ai penser a la commande create thread pour eviter de pénaliser mon appli.
J'ai bien regardé ton second site mais j'avoue avoir quelques difficultées de compréhension sur les fonctions suivantes.
-Waitcommevent
-setevenmask
-waitforsingleobject
-zeromemory

cette scrutation doit etre effective dés l'ouverture du port et s'arreter lors de la fermeture du port.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Le plus simple reste quand même le timer.
A l'ouverture du port, tu crée un Timer avec SetTimer (soit en donnant un hWnd et en traitant le message WM_TIMER, soit en donnant une fonction TimerProc). une cadence de 20 à 50 ms est suffisante).

A chaque appel du timer (dans WM_TIMER ou TimerProc), tu appelle ReadFile pour lire sur le port, et tu ajoute les données lues dans un buffer perso pour traitement (si t'as pas reçu tout ce dont tu avais besoin, tu stocke dans une variable globale en déplaçant un index ou un pointeur sur le buffer pour la prochaine lecture). Dès que tu as ce que tu veux dans ce buffer, tu le traite et tu met à jour l'indice où tu vas mettre les prochaine données à lire.
La fonction GetCommProperties peut te permettre de savoir s'il y a des octets à lire sur le port.

Explication des fonctions :

* WaitCommEvent : permet d'attendre (sans consommer de temps CPU) qu'un évènement survienne sur le port (Réception, envoi de données, signaux spéciaux...) en fonction d'un masque des évènements à surveiller initialisé par SetCommMask. Nécessite d'être fait dans un thread à part car bloquant. Cette attente peut être interrompue si un autre thread met à 0 le masque des évènements à surveiller. Sous XP c'était un poil plus compliqué car il fallait mettre le flag FILE_FLAG_OVERLAPPED dans CreateFile et faire une boucle d'attente de l'évènement assez compliquée en récupérant le code d'erreur par GetLastError.

* WaitForSingleObject : Sous Windows, la plupart des HANDLE crée (Fichiers, threads, process) ont un état dit signalé lorsqu'ils ont terminés une tache. Dans le cas d'un thread, son handle est "signalé" lorsqu'il est terminé. Ainsi, lorsque le thread principal demande la fermeture du port, il indique au thread de lecture qu'il doit se terminer (en mettant un booléen à FALSE). Le thread sort de sa boucle infinie et la Fonction WaitForSingleObject retourne de son attente. Dans ce prog, j'ai du mettre une boucle de traitement des messages lors de l'attente car le thread secondaire est suceptible d'envoyé un message au thread principal pendant qu'il attend, provoquant un deadlock (tout le monde s'attend)

* ZeroMemory : permet de mettre à 0 une zone mémoire, comme avec memset(pointeur, 0, taille).

pour en savoir plus sur les threads et leurs synchronisation :
http://brunews.free.fr/brunews/download/JR4.zip

http://brunews.free.fr/brunews/download/JR4Sources.zip
Messages postés
4
Date d'inscription
mercredi 10 mars 2004
Statut
Membre
Dernière intervention
7 juin 2004

Un grand merci , ymca2003

je viens de faire un test pour le timer , c'est ok manque plus que de le tester sur le port serie.

Pourrais-tu poursuivre ton aide sur le point suivant.

Aprés recupération de ma trame dans une variable , je désire l'afficher dans ma dialog box dés sa reception .
Seulement voila , je débute et je sais uniquement traiter des fonctions a partir d'evenement dialogbox button.....etc.
Comment puis-je réaliser une fonction qui puis etre scruter en permanance par dialogbox et m'afficher le contenu de la variable si il y a eu une reception?????.

Rappel : je developpe sous Visual 6 c++ , et j'utilise les MFC pour ma dialog box.

merci de ta réponse .
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
il te suffit de crééer un message perso et de l'envoyer par sendmessage à ton dialog (si c'est le dialogu principal, tu l'obtient en faisant AfxGetApp()->m_pMainWnd)

C'est de cette façon que je procède dans mon prog sérial pour notifier la fenêtre principale.

pour wParam, tu peut par exemple mettre le nombre d'octet reçu et dans lParam un pointeur sur le buffer avec les données.

=> dès que tu as reçu les données, tu fait :
pDlg->SendMessage(WM_MSG_PERSO, nbOctet, (LPARAM) buffer);

avec WM_MSG_PERSO une constante définie dans un header (celui de l'app par exemple) :
#define WM_MSG_PERSO (WM_USER+0x0100)
=> tu peut définir autant de message person que tu veut il te suffit qu'ils aient une valur > WM_USER.

Ensuite, dans ton dialog, il te suffit de traiter ce message.

dans le .h , au niveau du traitement des messages, mais en dehors des balises AFX__MSG :
afx_msg LRESULT OnMsgPerso(WPARAM wParam, LPARAM lParam);

dans le .cpp, dans la message table (en dehors des balises AFX_MSG) :
ON_MESSAGE(WM_MSG_PERSO, OnMsgPerso)

et en fin la fct de traitement :
LRESULT CTonDlg::OnMsgPerso(WPARAM wParam, LPARAM lParam)
{
// ici tu as une fct membre tu dialog qui a acces à ton les contrôle, avec dans wParam et lParam les param passés
return 0;
}
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
Si le timer est crée directement par le dialogue c'est encore plus simple car la fonction de traitement OnTimer a directement accès aux membres du dialogue et à tous les contrôles.
Messages postés
4
Date d'inscription
mercredi 10 mars 2004
Statut
Membre
Dernière intervention
7 juin 2004

Plouf !!!!!!!!!!!!!!!!

As tu un exemple , car la , je suis un peux perdu....
tu parles d'un proogramme , est-il sur le site codes sources.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
le 2 ème lien du post un peu plus haut.
Messages postés
1
Date d'inscription
samedi 4 décembre 2004
Statut
Membre
Dernière intervention
23 décembre 2004

bonjour,
jé tj des probléme avec la lecture du port serie quand j'utilise les threads mé quand j'utilise une simple fonction de reception (pas inclu ds un thread),il marche tre bien mé mon projet est de realiser la lecture du port com en utilisant les threads,svp ide moi mon amail :aboub12@caramail.com