2009-06-04 4 views
4

J'ai écrit/supporté un émulateur de terminal appelé uCon (http://www.umonfw.com/ucon). Tout est basé sur "bon-ole" Win32, et est entièrement en "C". On m'a récemment demandé de prendre en charge la possibilité d'attacher uCon à un port COM et de configurer DTR/RTS à des fins autres que le contrôle de flux RS232. Je sais que je peux le faire après l'appel de CreateFile() en utilisant EscapeCommFunction() et/ou SetCommState(); cependant, ces fonctions peuvent seulement être appelées AFTER CreateFile() retourne un handle au port ouvert. Malheureusement, lorsque CreateFile() ouvre le port, il définit DTR/RTS sur leur état par défaut, qui peut (ou non) être différent de l'état dans lequel je souhaite conserver DTR.Comment définir l'état DTR/RTS qui sera utilisé lorsque CreateFile() ouvre le port COM

Par exemple, supposons que l'utilisateur a une carte connectée au port série du PC, et la ligne DTR est utilisée pour mettre la carte dans un état non standard. Lorsque DTR est inactif, la carte s'exécute "normalement", mais occasionnellement, DTR-active est utilisé pour faire passer le matériel à un autre état.

Dans la plupart des cas, j'ai vu, CreateFile() active DTR, puis mon appel pour effacer DTR le ramène à inactif; Cependant, c'est un petit problème que je dois éviter. J'ai trouvé un jeu de fonctions appelé GetDefaultCommConfig() & SetDefaultCommConfig() mais je n'ai pas réussi à les faire fonctionner correctement. Donc, ma question est la suivante ...

Y at-il un moyen de prédéfinir l'état par défaut qui sera établi sur les lignes de contrôle RS232 lorsque CreateFile() est appelé? Quelqu'un a-t-il utilisé GetDefaultCommConfig()/SetDefaultCommConfig() avec succès?

Il me semble que cela devrait me permettre de préétablir la valeur de DTR être utilisé lorsque CreateFile() est appelée ...

 
int 
EstablishDefaultDTR(char *comPortName, int dtr) 
{ 
    COMMCONFIG cc; 
    DWORD bsize = sizeof(COMMCONFIG); 

    if (GetDefaultCommConfig(comPortName,&cc,&bsize) == 0) { 
     ShowLastError("GetDefaultCommConfig()"); 
     return(-1); 
    } 

    if (dtr) 
     cc.dcb.fDtrControl = DTR_CONTROL_ENABLE ; 
    else 
     cc.dcb.fDtrControl = DTR_CONTROL_DISABLE ; 

    if (SetDefaultCommConfig(comPortName,&cc,bsize) == 0) { 
     ShowLastError("SetDefaultCommConfig()"); 
     return(-1); 
    } 
} 

Mais, comme vous l'avez déjà deviné, ce n'est pas le cas. Des idées?

+0

Avez-vous regardé ici: http://msdn.microsoft.com/en-us/library/ms810467.aspx L'article offre BuildCommDCB () comme alternative ... peut-être que cela fera l'affaire pour vous? –

+0

@Ed: J'ai le même problème. Pourriez-vous le résoudre? J'offre une prime. –

+0

Avez-vous regardé ici: http://www.codeguru.com/forum/showthread.php?t=291244 Même problème à portée de main. Toutefois, TDM prétend que la définition du DTR à son état après l'ouverture du port est la seule manière définie de le faire. Si un retard de commutation de 100 ms tue le matériel, il y a un défaut de conception dès le début. – Bort

Répondre

2

Vous n'initialisez pas la structure COMMCONFIG. Cela pourrait bien être le problème puisque la documentation indique explicitement que vous devez définir dwSize au moins

cc.dwSize = sizeof (COMMCONFIG);

+0

Juste le faire avant le premier appel n'a pas fonctionné. Les deux appels retournent non nul, donc, apparemment, ils réussissent. Après l'appel de 'GetDefaultCommConfig', j'ai vérifié le contenu de' cc' et la seule chose étrange que j'ai vu était que 'cc.dcb.DCBLength' égalait' 3435973836'. Je vais essayer d'utiliser 'BuildCommDCB' avant le premier appel. Toute autre suggestion est la bienvenue. –

+0

J'ai trouvé une solution de contournement et l'ai affichée comme réponse. J'attendrai que la prime expire pour voir si quelqu'un trouve une meilleure solution de travail. –

+0

@dario_ramos Est-ce que BuildCommDCB ne fonctionnait pas non plus? – Danra

3

peut-être pas le meilleur moyen, mais cela fonctionne:

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

int 
EstablishDefaultDTR(char *comPortName, int dtr){ 
    char commandString[256]; 
    if (!system(NULL)){ 
     ShowLastError("system()"); 
     return(-1); 
    }   
    sprintf(commandString, "MODE %s dtr=%s%", comPortName, dtr? "on":"off" ); 
    return system(commandString); 
} 
+0

Cela ne fait-il pas que s'ouvrir le port et définir l'état DTR? Si le port est déjà ouvert, la commande 'MODE' échoue. La prochaine fois que vous ouvrez le port, il conserve l'état précédent. Vous pouvez obtenir le même comportement en ouvrant un port, en définissant DTR, en fermant le port, puis en l'ouvrant à nouveau dans le code. – tinman

+0

Je fais cela avant de l'ouvrir et cela fonctionne. Je n'ai pas vérifié si l'appel à 'CreateFile' réussit, mais le port est ouvert avec l'état correct de DTR (avant, il a TOUJOURS commencé avec le jeu de DTR), et la communication fonctionne comme prévu. –

+0

Même si j'ai ouvert le port, effacé DTR, fermé et ouvert à nouveau plus tard, je pouvais voir le matériel réagir pendant la petite période où DTR a été réglé (une led a été allumée et un tube xray filé pendant une demi-seconde). Avec cette solution, cela n'arrive pas du tout. –

Questions connexes