2010-11-15 302 views
3

我正在尝试编写使用串行端口(例如COM8)的C++ MFC应用程序。每次我尝试设置DCB时都会失败。如果有人能指出我做错了什么,我会非常感激。尝试配置COM端口时设置DCB失败

DCB dcb = {0}; 

dcb.DCBlength = sizeof(DCB); 
port.Insert(0, L"\\\\.\\"); 

m_hComm = CreateFile(
    port,       // Virtual COM port 
    GENERIC_READ | GENERIC_WRITE, // Access: Read and write 
    0,        // Share: No sharing 
    NULL,       // Security: None 
    OPEN_EXISTING,     // The COM port already exists. 
    FILE_FLAG_OVERLAPPED,   // Asynchronous I/O. 
    NULL       // No template file for COM port. 
    ); 

if (m_hComm == INVALID_HANDLE_VALUE) 
{ 
    TRACE(_T("Unable to open COM port.")); 
    ThrowException(); 
} 

if (!::GetCommState(m_hComm, &dcb)) 
{ 
    TRACE(_T("CSerialPort : Failed to get the comm state - Error: %d"), GetLastError()); 
    ThrowException(); 
} 

dcb.BaudRate = 38400;    // Setup the baud rate. 
dcb.Parity = NOPARITY;    // Setup the parity. 
dcb.ByteSize = 8;     // Setup the data bits. 
dcb.StopBits = 1;     // Setup the stop bits. 

if (!::SetCommState(m_hComm, &dcb)) // <- Fails here. 
{ 
    TRACE(_T("CSerialPort : Failed to set the comm state - Error: %d"), GetLastError()); 
    ThrowException(); 
} 

谢谢。

附加信息:生成的错误代码是87:“该参数不正确。” 可能是微软的大多数有用的错误代码。 j/k

+0

您可以提及错误代码。 – Amnon 2010-11-15 21:05:39

+0

@Amnon:好的,我将错误代码信息添加到了我原来的帖子中,但我认为它没有多大帮助。 – 2010-11-15 21:09:00

回答

1

我能解决使用BuildCommDCB问题:

DCB dcb = {0}; 

if (!::BuildCommDCB(_T("baud=38400 parity=N data=8 stop=1"), &dcb)) 
{ 
    TRACE(_T("CSerialPort : Failed to build the DCB structure - Error: %d"), GetLastError()); 
    ThrowException(); 
} 
+0

那么显式设置的字段和BuildCommDCB之间的区别是什么?或者我们不在乎,只要它现在在工作! – Jeff 2010-11-15 23:57:41

+0

我只是想让它工作。我已经投票通过的关于停止位的评论可能是正确的。 – 2010-11-18 14:41:24

+1

高超的解决方法:) – 2016-02-21 13:55:37

0

看看你给这个函数的参数。正如错误代码所说,它们可能不正确。搜索“SetCommState 87”的谷歌搜索显示了几个参数(例如波特率)与串口不兼容的情况。

2

这里有没有特定的顺序一些可能性。

  • GetCommState由于端口尚未初始化,所以正在填充垃圾结构。你可以跳过这一步。
  • 有两个控制奇偶校验设置的参数,并且不清楚是否有任何无效组合。
  • StopBits的值不是位数,它是一个幻数常量。值1等于ONE5STOPBITS,与其他参数结合使用时可能无效。
+0

感谢您的提示。他们绝对值得记住。 – 2010-11-15 22:12:26

8

我的钱是这样的:

dcb.StopBits = 1; 

The MSDN docs说,这大约停止位:使用

停止位的数量。此成员可以是以下值之一: 。

ONESTOPBIT 0 1 stop bit. 
ONE5STOPBITS 1 1.5 stop bits. 
TWOSTOPBITS 2 2 stop bits. 

所以,你问1.5个停止位,这是这样的,我可以不记得它来自一个古老的可怕的事情。可能是Teleprinters。

我想你的驱动程序/硬件支持这种模式的机会很渺茫,因此错误。

因此,将其更改为dcb.StopBits = ONESTOPBIT;