有了鲜血和泪水,我发现每当你调用GetCommState时,DCB结构的fParity成员都会被主动设置为FALSE。
是否有解决方法(除了明确设置dcb.fParity = 1;每次需要调用SetCommState时)?有没有人遇到过这个问题?有没有MSDN文章解释这种行为?
这是一个在我的电脑上重现问题的MCVE:
int main()
{
HANDLE hComm;
DCB dcb;
// Replace COM1 by any COM port identifier on your PC
hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hComm == INVALID_HANDLE_VALUE)
{
printf("Failed COM opening. Exit.");
return -1;
}
FillMemory(&dcb, sizeof(dcb), 0);
dcb.DCBlength = sizeof(dcb);
// Get the current DCB structure
if (!GetCommState(hComm, &dcb))
{
printf("Failed GetCommState. Exit.");
return -1;
}
// [Here, you may set any or all members of the dcb structure]
// As suggested by chux and Hans Passant in a comment, try to set the parity to make the fParity value relevant.
dcb.Parity = MARKPARITY;
// This is the relevant bit :
dcb.fParity = TRUE;
// Set the new COM state.
if (!SetCommState(hComm, &dcb))
{
printf("Failed SetCommState. Exit.");
return -1;
}
// Read back the COM state (fParity should be TRUE)
if (!GetCommState(hComm, &dcb))
{
printf("Failed GetCommState. Exit.");
return -1;
}
printf("fParity = %d\n", dcb.fParity); // fParity value is 0.
CloseHandle(hComm);
}
GetCommState()之后唯一没有正确读回的值是fParity。
答案 0 :(得分:1)
I contacted Microsoft about that and the semi-official answer is that yes, indeed, there's a bug with the fParity
member of the DCB structure, as the value isn't read back properly by GetCommState()
. The value of fParity
will always be false (even though the documentation says that the default value is true).
They also informed me that the fParity
flag isn't checked at all by the driver, and that parity errors are reported (or not) based on the Parity
flag setting.
That last bit of information stumped me a little bit, as the MSDN page about DCB specifically indicates that another member of the structure, fErrorChar
, doesn't take effect unless fParity
is true. I never got a satisfactory explanation about the behavior of fErrorChar
.
I suspect the MSDN documentation to be misleading about the COM driver's capabilities, which embarrasses Microsoft. And anyway, this can't be fixed unless a host of legacy applications suddenly face backward compatibility issues.
答案 1 :(得分:-1)
从上面的代码看起来你正在使用标记和空间奇偶校验方案进行通信。当您致电GetCommState
时,您在Parity
字段中获得了什么。
由于GetCommState
未将fParity
作为True
返回,因此可能有助于调用ClearCommError
并检查第二个参数COMSTAT
是否有CE_RXPARITY
。在你的情况下不确定它是否有效但是在收到端口上的一些数据后调用ClearCommError
时它应该可以工作。