| |
|
Serial Communication Class for 32-bit Applications
The article was published in the July '97 issue of The C/C++ User's
Journal.
A copy of the article is available online
here.
The archive containing the code is available here:
CUJArticle.zip (43.1K).
A problem common to anyone porting 16-bit serial communication
code to 32-bit Windows NT or Windows 95 is that the familiar methods of
performing that task are at the very least different and at the worst,
no longer present. The article presented a class that encapsulates the
Win32 API functions used for serial communication and simplifies their
use. The class also contains some member functions that make it simple
to start and stop a separate thread for sending and receiving data. Some
sample programs were included to demonstrate how the class can be
used.
It is not explicitly stated in the article, but permission is
hereby given to use any and all source code from the article in your own
projects as long as my copyright notice remains in the source files.
Terminal.cpp and TermPoll.cpp
The DumbTerminal() function in both files needs to be corrected
to set the stop bits option correctly.
if(pszOptions[2] == '2')
nStopBits = TWOSTOPBITS; // <----- nStopBits instead of nDataBits
GuiTermDoc.cpp
CGUITermDoc::OnFileConnect() needs to set
the selected baud rate. Here's the affected section of code:
if(m_csFlowControl == "Software")
nFlow = PCF_XONXOFF;
else
if(m_csFlowControl == "None")
nFlow = PCF_NOFLOWCTL;
COMPort->SetBaudRate(nBaud); // <--- ADD THIS LINE
COMPort->SetParityDataStop(nParity, nData, nStop);
COMPort->SetFlowControl(nFlow);
SerialPort.cpp
CSerialPort::EscapeCommFunction() was incorrectly using the xxxDTR
and xxxRTS values. Replace it with this code:
BOOL CSerialPort::EscapeCommFunction(DWORD dwFunc)
{
DCB dcb;
BOOL bRetVal;
dwLastError = ERROR_SUCCESS;
dwLastError = ERROR_SUCCESS;
dcb.DCBlength = sizeof(DCB);
::GetCommState(hPortId, &dcb);
// The EscapeComm() function should not be used to adjust line
// settings if dcb.fDtrControl is set to DTR_CONTROL_HANDSHAKE
// or dcb.fRtsControl is set to RTS_CONTROL_HANDSHAKE or
// RTS_CONTROL_TOGGLE (that's what is says in the online help
// for the DCB structure).
if((dcb.fDtrControl & DTR_CONTROL_HANDSHAKE) &&
(dwFunc == CLRDTR || dwFunc == SETDTR))
return FALSE;
if((dcb.fRtsControl & (RTS_CONTROL_HANDSHAKE | RTS_CONTROL_TOGGLE)) &&
(dwFunc == CLRRTS || dwFunc == SETRTS))
return FALSE;
bRetVal = ::EscapeCommFunction(hPortId, dwFunc);
if(!bRetVal)
dwLastError = ::GetLastError();
return bRetVal;
}
If you see the above error message while trying to compile the code,
you need to turn off the precompiled header option for the SerialPort.cpp
source file as it is not using them. To do this you need to do the following:
- In the workspace window, right click on the SerialPort.cpp
source file and select the Settings option.
- In the C++ tab, change the Category combo box to Precompiled
Headers.
- Select the Not using precompiled headers option and click OK.
Now when you rebuild, precompiled headers won't be used for that source
file and it will compile without any errors.
|