2009-06-04 111 views
4

我写/支持名为uCon的终端仿真器(http://www.umonfw.com/ucon)。它的全部基于“good-ole”Win32,完全是'C'。最近我被要求支持将uCon连接到COM端口并为RS232流量控制之外的目的设置DTR/RTS的能力。我知道我可以在使用EscapeCommFunction()和/或SetCommState()调用CreateFile()后执行此操作。然而,这些函数只能在调用后被CreateFile()返回到打开的端口的句柄。不幸的是,当CreateFile()打开端口时,它将DTR/RTS设置为它们的默认状态,这可能(或可能不)与我希望保留DTR的状态不同。如何设置将在CreateFile()打开COM端口时使用的DTR/RTS状态

例如,假设用户有一个电路板连接到PC的串行端口,DTR线用于使电路板处于非标准状态。 DTR处于非活动状态时,电路板运行“正常”,但偶尔使用DTR活动将硬件转换为其他状态。

在大多数情况下,我已经看到,CreateFile()会使DTR处于活动状态,然后我的调用清除DTR会将其恢复为不活动状态;然而,这是我需要避免的一个小故障。我发现一个名为GetDefaultCommConfig()的函数集()& SetDefaultCommConfig(),但无法让它们成功工作。所以,我的问题是这样的...

当调用CreateFile()时,是否有方法来预先定义将在RS232控制线上建立的默认状态?有没有人成功使用GetDefaultCommConfig()/ SetDefaultCommConfig()?

在我看来,这应该让我预先建立DTR的值为时的CreateFile()被调用使用 ...

 
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); 
    } 
} 

但是,正如你可能已经猜到了,它没有。 有什么建议吗?

+0

有你看这里:http://msdn.microsoft.com/en-us/library/ms810467.aspx文章提供BuildCommDCB( )作为替代...也许这会为你做诡计? – 2009-08-03 03:53:21

+0

@Ed:我有完全相同的问题。你能解决它吗?我提供赏金。 – 2012-01-24 16:28:06

+0

你看过这里:http://www.codeguru.com/forum/showthread.php?t=291244同样的问题在眼前。然而,TDM声称在打开端口后将DTR设置为其状态是唯一确定的方式。如果一个100ms的开关延迟杀死了硬件,那么从一开始就存在设计缺陷。 – Bort 2012-01-31 11:50:16

回答

2

您未初始化COMMCONFIG结构。这可能是问题,因为文档明确指出您必须将dwSize设置为至少

cc.dwSize = sizeof(COMMCONFIG);

3

未必是最快的途径,但这个工程:

#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); 
}