在GetCommState之后,DCB结构的fParity成员总是为FALSE

时间:2016-04-04 19:43:14

标签: c winapi serial-port

有了鲜血和泪水,我发现每当你调用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。

2 个答案:

答案 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时它应该可以工作。