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
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;
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.
I was able to resolve the problem using 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();
}
This is my code and its working well.
/* 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");
Look at the parameters you give to the function. They're probably incorrect, as the error code says. A google search for "SetCommState 87" shows several instances where the parameters (e.g. baud rate) weren't compatible with the serial port.
来源:https://stackoverflow.com/questions/4188782/set-dcb-fails-when-attempting-to-configure-com-port