代码之家  ›  专栏  ›  技术社区  ›  Jim Fell

试图配置COM端口时设置DCB失败

  •  4
  • Jim Fell  · 技术社区  · 15 年前

    我正在尝试编写一个使用串口的C++ MFC应用程序(例如COM8)。每次我试着设置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公司

    5 回复  |  直到 13 年前
        1
  •  11
  •   Roddy    15 年前

    我的钱在这上面:

    dcb.StopBits = 1; 
    

    The MSDN docs 关于StopBits这样说:

    要使用的停止位的数目。此成员可以是 以下值。

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

    所以,你要求的是1.5个停止位,这是一个非常古老的东西,我甚至不记得它是从哪里来的。可能是电传打字机。

    我猜您的驱动程序/硬件支持此模式的可能性很小,因此出现错误。

    所以,把它改成 dcb.StopBits = ONESTOPBIT;

        2
  •  3
  •   Mark Ransom    15 年前

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

    • GetCommState 正在用垃圾填充结构,因为端口尚未初始化。你可以跳过这一步。
    • 有两个参数控制奇偶校验设置,不清楚是否有任何无效的组合。
    • StopBits的值不是位数,而是一个神奇的数字常量。值1等于 ONE5STOPBITS 与其他参数组合时可能无效。
        3
  •  2
  •   Jim Fell    15 年前

    我能用 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();
    }
    
        4
  •  1
  •   user1810087 Akin Ocal    7 年前

    这是我的代码,运行良好。

    /* Try to open the port */
    hCom = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
    
    if (hCom != INVALID_HANDLE_VALUE) {
        printf("Handle success\n");
    }
    
        dcb = { 0 };
        dcb.DCBlength = sizeof(dcb);
    
        fSuccess = GetCommState(hCom, &dcb);
    
        if (!fSuccess) {
            // Handle the error.
            printf("GetCommState failed with error %d.\n", GetLastError());
            CloseHandle(hCom);
            return APP_ERROR;
        }
    
        // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.
        dcb = { 0 };
        dcb.DCBlength = sizeof(dcb);
    
        dcb.BaudRate = CBR_115200;     // Set the baud rate
        dcb.ByteSize = 8;              // Data size, xmit, and rcv
        dcb.Parity = NOPARITY;         // No parity bit
        dcb.StopBits = ONESTOPBIT;     // One stop bit
    
        fSuccess = SetCommState(hCom, &dcb);
    
        if (!fSuccess) {
            // Handle the error.
            printf("SetCommState failed with error %d.\n", GetLastError());
            CloseHandle(hCom);
            return APP_ERROR;
        }
    }
    
    printf("Serial port successfully reconfigured.\n");
    
        5
  •  0
  •   Amnon    15 年前

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