Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set DCB Fails When Attempting to Configure COM Port

I'm trying to write a C++ MFC application that uses the serial port (e.g. COM8). Every time I try to set the DCB it fails. If someone can point out what I'm doing wrong, I'd really appreciate it.

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();
}

Thanks.

Additional Info: The generated error code is 87: "The parameter is incorrect." Probably Microsoft's most useful error-code. j/k

like image 832
Jim Fell Avatar asked Nov 15 '10 21:11

Jim Fell


2 Answers

My money is on this:

dcb.StopBits = 1; 

The MSDN docs says this about StopBits:

The number of stop bits to be used. This member can be one of the following values.

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

So, you're asking for 1.5 stop bits, which is such a horribly archaic thing I can't even remember where it comes from. Teleprinters, possibly.

I'd guess the chances of your driver/hardware supporting this mode are slim, hence the error.

So, change it to dcb.StopBits = ONESTOPBIT;

like image 165
Roddy Avatar answered Oct 03 '22 09:10

Roddy


Here are some possibilities in no particular order.

  • GetCommState is filling the structure with garbage since the port hasn't been initialized yet. You might just skip this step.
  • There are two parameters that control the Parity settings, and it's not clear if there's any invalid combinations.
  • The value for StopBits is not the number of bits, it's a magic number constant. The value 1 equates to ONE5STOPBITS which might be invalid when combined with the other parameters.
like image 28
Mark Ransom Avatar answered Oct 03 '22 09:10

Mark Ransom