How to Set Baud Rate 28800 Using DCB Structure
Categories:
Setting Baud Rate 28800 with DCB Structure in C++

Learn how to configure a serial port to a non-standard baud rate of 28800 using the DCB (Device Control Block) structure in C++ on Windows.
Communicating with serial devices often requires precise control over parameters like the baud rate. While standard baud rates are readily available, some legacy or specialized hardware might require non-standard rates. This article focuses on setting a baud rate of 28800 using the DCB
structure in C++ on Windows, a rate not directly supported by the standard CBR_
constants.
Understanding the DCB Structure
The DCB
(Device Control Block) structure is a crucial component for configuring serial communication parameters on Windows. It contains various fields that control aspects like baud rate, parity, stop bits, and flow control. When setting a non-standard baud rate, we need to directly manipulate the BaudRate
member of this structure.
flowchart TD A[Open Serial Port] --> B{Get Current DCB Settings} B --> C[Modify DCB.BaudRate to 28800] C --> D[Set New DCB Settings] D --> E[Configure Timeouts] E --> F[Start Communication] F --> G[Close Serial Port]
Flowchart of the serial port configuration process
The Challenge with Non-Standard Baud Rates
Windows provides a set of predefined constants (e.g., CBR_9600
, CBR_115200
) for common baud rates. However, for rates like 28800, these constants are not available. Attempting to pass 28800
directly to functions like SetCommState
might not work as expected if the underlying driver doesn't explicitly support it or if the DCB
structure isn't correctly populated. The key is to ensure the BaudRate
member is set to the desired value and that the fBinary
flag is set to TRUE
for raw binary mode.
#include <windows.h>
#include <iostream>
// Function to set the baud rate to 28800
BOOL SetBaudRate28800(HANDLE hSerial)
{
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
std::cerr << "Error getting current serial port state.\n";
return FALSE;
}
// Set non-standard baud rate
dcbSerialParams.BaudRate = 28800; // Directly set the desired baud rate
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
dcbSerialParams.fBinary = TRUE; // Essential for raw data and custom baud rates
if (!SetCommState(hSerial, &dcbSerialParams)) {
std::cerr << "Error setting serial port state. Error code: " << GetLastError() << "\n";
return FALSE;
}
std::cout << "Baud rate set to 28800 successfully.\n";
return TRUE;
}
int main()
{
HANDLE hSerial;
LPCSTR sPortName = "COM1"; // Change to your serial port name
hSerial = CreateFileA(
sPortName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hSerial == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening serial port. Error code: " << GetLastError() << "\n";
return 1;
}
if (!SetBaudRate28800(hSerial)) {
CloseHandle(hSerial);
return 1;
}
// Configure timeouts (important for reliable communication)
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)) {
std::cerr << "Error setting serial port timeouts.\n";
CloseHandle(hSerial);
return 1;
}
std::cout << "Serial port configured. Ready for communication.\n";
// Example: Write a byte
// char data_to_send = 'A';
// DWORD bytes_written;
// if (!WriteFile(hSerial, &data_to_send, 1, &bytes_written, NULL)) {
// std::cerr << "Error writing to serial port.\n";
// }
// Example: Read a byte
// char received_data;
// DWORD bytes_read;
// if (ReadFile(hSerial, &received_data, 1, &bytes_read, NULL)) {
// if (bytes_read > 0) {
// std::cout << "Received: " << received_data << "\n";
// }
// }
CloseHandle(hSerial);
return 0;
}
GetCommState
and SetCommState
. Use GetLastError()
to retrieve detailed error information if a function fails. This is crucial for debugging serial communication issues.Key Considerations for Non-Standard Baud Rates
When working with non-standard baud rates, several factors are important to keep in mind:
- Driver Support: The serial port hardware and its driver must genuinely support the desired baud rate. While you can set
DCB.BaudRate
to any integer, the hardware might not be able to generate that exact frequency, leading to communication errors. fBinary
Flag: SettingdcbSerialParams.fBinary = TRUE;
is often critical. This flag enables raw binary mode, which is usually required when you're bypassing standard baud rate constants and directly specifying the rate.- Timeouts: Proper configuration of
COMMTIMEOUTS
is essential for reliable serial communication, especially when reading data. Without appropriate timeouts,ReadFile
calls can block indefinitely or return prematurely. - Error Handling: Robust error handling using
GetLastError()
is vital. Serial communication can be finicky, and detailed error messages will save significant debugging time. - Device Compatibility: Ensure the device you are communicating with is also configured to use the exact same 28800 baud rate, along with matching data bits, stop bits, and parity settings.