我有一个从 VC++ 6 移植过来的应用程序,它运行良好。有问题的代码将 WinAPI 用于串行设备驱动程序。当移植到 VS2012 时,相同的代码表现得非常不同。
创建一个 DCB,设置 SetCommState 并开始。CTS 设置得很高,RTS 设置得很高,你就在路上。
由于移植到 VS2012 Pro MFC,我发现无论有没有硬件流控制,它都设置了相同的 SetCommState:
memset(&dcb, 0x00, sizeof(dcb));
dcb.DCBlength = sizeof(DCB);
// Must be TRUE, only binary mode in Windows
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
// XOn/XOff disabled
dcb.fTXContinueOnXoff = TRUE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.XonLim = 0;
dcb.XoffLim = 0;
dcb.XonChar = 0;
dcb.XoffChar = 0;
// Misc Stuff
dcb.EofChar = 0;
dcb.EvtChar = 0;
dcb.ErrorChar = 0;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;
// 8N1 Setup
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
// Baud Rate
if (dwBaudRate == BAUD_115200)
{
dcb.BaudRate = CBR_115200;
}
else
{
dcb.BaudRate = CBR_38400;
}
// setup hardware flow control
if (bHardware == eYesHardwareFlowControl)
{
// ================ FLOW CONTROL ON ================
switch (bIgnoreCTS)
{
case eIgnoreCTS:
dcb.fOutxCtsFlow = FALSE;
break;
case eEnableCTS:
dcb.fOutxCtsFlow = TRUE;
break;
default:
case eCTSDecideLater:
dcb.fOutxCtsFlow = TRUE;
break;
}
// DSR Flow Control
dcb.fDsrSensitivity = FALSE;
dcb.fOutxDsrFlow = FALSE;
// <<Hardware flow control On(TRUE) Off(FALSE)>>
dcb.fDtrControl = DTR_CONTROL_ENABLE;
// <<Hardware flow control On(_HANDSHAKE) Off(_ENBLE)>>
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
}
else
{
// ================ FLOW CONTROL OFF ================
switch (bIgnoreCTS)
{
case eIgnoreCTS:
dcb.fOutxCtsFlow = FALSE;
break;
case eEnableCTS:
dcb.fOutxCtsFlow = TRUE;
break;
default:
case eCTSDecideLater:
dcb.fOutxCtsFlow = FALSE;
break;
}
// DSR Flow Control
dcb.fDsrSensitivity = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
}
if (SetCommState(m_hIdComDev, &dcb) == WINDOWS_API_ZERO_IS_BAD)
{
dwLastError = GetLastError();
}
至此,我已经设置了 DCB,清除了它。我没有读到以前的状态是我不想相信以前使用该端口的任何人的任何垃圾。然后我将每个字段设置为波特、流控制和 CTS 忽略作为唯一的可选项目。
所以,我注意到的是,我可以创造设备和 PC 不通信的情况。现在,请注意,他们以前总是这样做,而且他们总是使用 Hyperterminal、ProComm、TeraTerm 等。我可以看到,当这些通讯程序启动(以及旧的 VC++ 6 应用程序)时,当设备被创建和设置时,RTS 立即被设置为高电平。
现在,我的应用程序,一旦设置了 DCB,就会调用 SetCommState;RTS 始终为低电平。当这种情况发生时,沟通就完蛋了。
我想强制 RTS 变高,并认为我可以这样做:
if (EscapeCommFunction(m_hIdComDev, CLRRTS) == WINDOWS_API_ZERO_IS_BAD)
{
dwLastError = GetLastError();
}
if (EscapeCommFunction(m_hIdComDev, SETRTS) == WINDOWS_API_ZERO_IS_BAD)
{
dwLastError = GetLastError();
}
但这失败了,它给出了错误 87(参数错误)。我无法完全弄清楚。即使我只是设置高,它也失败了。
关于在 DCB 中设置通信参数后如何强制 Windows 将 RTS 设置为高的任何想法?