📄 comwin32.cpp
字号:
/************************************************************************
*
* Module name : ComWin32.cpp
*
* Module description :
* Declaration of class ComWin32.
* ComWin32 is a class which operates the RS232 port.
*
* NOTE: I hate Microsoft!!! They never give you enough information.
*
* When using WaitCommEvent() with overlapped, the kernel will
* remember the address of the second parameter of the function,
* which is the address of the variable to store the value of the
* received events. This address will be rememberred by the kernel
* as soon as you make the first call to the WaitCommEvent(). Bloody
* Microsoft DOES NOT tell you that the address will be rememberred!
* Using a local variable when calling this function will cause the
* application to crash, sooner or later. So DO NOT use the local
* variable as the second parameter when calling WaitCommEvent().
*
* Project : Generic.
*
* Target platform : Win32
*
* Compiler & Library : Visual C++ 6.0
*
* Author : Richard Shen
*
* Creation date : 30 August, 1999
*
* Modifications :
* 04May03 RCS WaitForTxComplete() added.
*
************************************************************************/
#include <windows.h>
#include "ComWin32.h"
/************************************************************************
* Function name : ComWin32::ComWin32
* Description : Constructor of class.
* :
* Parameters : portNo - COM port.
* : rxBufSize - Rx buffer size. Default COM_RXBUFSZ.
* : txBufSize - Tx buffer size. Default COM_TXBUFSZ.
* : dtrInitHigh - Whether to raise DTR when openning.
* : Default to TRUE.
* : rtsInitHigh - Whether to raise RTS when openning.
* : Default to TRUE.
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 30Aug99 RCS Created.
************************************************************************/
ComWin32::ComWin32(int portNo, int rxBufSize, int txBufSize,
BOOL dtrInitHigh, BOOL rtsInitHigh
)
{
comHandle = INVALID_HANDLE_VALUE;
comID = portNo;
rxQueue = rxBufSize;
txQueue = txBufSize;
comLastError = NO_ERROR;
#ifndef NO_OVERLAPPED_SUPPORT
comEventMask = 0;
#endif // !NO_OVERLAPPED_SUPPORT
inHandshake = HS_NONE;
outHandshake = HS_NONE;
circular = new Circular(rxQueue);
memset(&comDCB, 0, sizeof(DCB));
memset(&comTimeOuts, 0, sizeof(COMMTIMEOUTS));
#ifndef NO_OVERLAPPED_SUPPORT
memset(&ovReadWrite, 0, sizeof(OVERLAPPED));
memset(&ovComEvent, 0, sizeof(OVERLAPPED));
// Create an event object for COM events
ovReadWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ovComEvent.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
#endif // !NO_OVERLAPPED_SUPPORT
delayHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
// Open and initialize the port
Initialize(dtrInitHigh, rtsInitHigh);
} // ComWin32::ComWin32()
/************************************************************************
* Function name : ComWin32::~ComWin32
* Description : Destructor of class.
* :
* Parameters : -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 30Aug99 RCS Created.
************************************************************************/
ComWin32::~ComWin32(void)
{
// Close COM port
Close();
if (circular != 0)
delete circular;
// Release handles
#ifndef NO_OVERLAPPED_SUPPORT
if (ovReadWrite.hEvent != 0)
CloseHandle(ovReadWrite.hEvent);
if (ovComEvent.hEvent != 0)
CloseHandle(ovComEvent.hEvent);
#endif // !NO_OVERLAPPED_SUPPORT
if (delayHandle != 0)
CloseHandle(delayHandle);
return;
} // ComWin32::~ComWin32()
/************************************************************************
* Function name : ComWin32::IsPortAvailable
* Description : Check whether the object is OK to operate the port.
* :
* Parameters : -
* Returns : TRUE - OK.
* : FALSE - Unavailable.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
BOOL ComWin32::IsPortAvailable(void)
{
if (comHandle == INVALID_HANDLE_VALUE)
return FALSE;
return TRUE;
} // ComWin32::IsPortAvailable()
/************************************************************************
* Function name : ComWin32::Open
* Description : Open COM port.
* :
* Parameters : -
* Returns : Error code.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 30Aug99 RCS Created.
************************************************************************/
DWORD ComWin32::Open(void)
{
char portName[MAX_PATH];
wsprintf(portName, "\\\\.\\COM%d", comID + 1);
comHandle = CreateFile(portName, // Name
GENERIC_READ | GENERIC_WRITE, // Access mode
0, // Share mode
NULL, // Security attributes
OPEN_EXISTING, // How to create
#ifndef NO_OVERLAPPED_SUPPORT
FILE_FLAG_OVERLAPPED |
#endif // !NO_OVERLAPPED_SUPPORT
FILE_ATTRIBUTE_NORMAL, // File attributes
NULL // Template
);
if (comHandle == INVALID_HANDLE_VALUE)
comLastError = GetLastError();
else
comLastError = NO_ERROR;
return comLastError;
} // ComWin32::Open()
/************************************************************************
* Function name : ComWin32::Close
* Description : Close COM port.
* :
* Parameters : -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 30Aug99 RCS Created.
************************************************************************/
void ComWin32::Close(void)
{
if (comHandle != INVALID_HANDLE_VALUE)
{
SetEventMask(0); // Disable all COM events
LineSignal(DTR, SIGNAL_OFF);
LineSignal(RTS, SIGNAL_OFF);
CloseHandle(comHandle);
} /* end of if */
comHandle = INVALID_HANDLE_VALUE;
} // ComWin32::Close()
/************************************************************************
* Function name : ComWin32::Initialize
* Description : Open and initialize the COM port.
* :
* Parameters : dtrInitHigh -
* : rtsInitHigh -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 30Aug99 RCS Created.
************************************************************************/
void ComWin32::Initialize(BOOL dtrInitHigh, BOOL rtsInitHigh)
{
if (Open() != NO_ERROR)
return; // Cannot open COM port
SetupComm(comHandle, rxQueue, txQueue);
SetCommMask(comHandle, 0); // Disable all events
GetCommState(comHandle, &comDCB); // Get the state of COM port
// Initialize communication parameters
comDCB.BaudRate = CBR_19200;
comDCB.ByteSize = 8;
comDCB.Parity = NOPARITY;
comDCB.StopBits = ONESTOPBIT;
comDCB.fOutxCtsFlow = 0;
comDCB.fOutxDsrFlow = 0;
comDCB.fDtrControl = (dtrInitHigh) ? DTR_CONTROL_ENABLE :
DTR_CONTROL_DISABLE;
comDCB.fRtsControl = (rtsInitHigh) ? RTS_CONTROL_ENABLE :
RTS_CONTROL_DISABLE;
comDCB.fBinary = 1;
comDCB.fNull = 0;
comDCB.EofChar = 0;
comDCB.EvtChar = 0;
comDCB.XonChar = XON; // Specify the Xon character
comDCB.XoffChar = XOFF; // Specify the Xoff character
comDCB.XonLim = (unsigned short )(rxQueue / 4);
comDCB.XoffLim = 128;
// Get the timeout values for the port and set our timeout values.
COMMTIMEOUTS newComTimeOuts;
GetCommTimeouts(comHandle, &comTimeOuts);
newComTimeOuts.ReadIntervalTimeout = MAXDWORD;
newComTimeOuts.ReadTotalTimeoutConstant = 0;
newComTimeOuts.ReadTotalTimeoutMultiplier = 0;
newComTimeOuts.WriteTotalTimeoutMultiplier = 0;
newComTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(comHandle, &newComTimeOuts);
// Now lets try to set the port to our default values.
if (!SetCommState(comHandle, &comDCB))
comLastError = GetLastError();
return;
} // ComWin32::Initialize()
/************************************************************************
* Function name : ComWin32::BaudRate
* Description : Set baud rate.
* :
* Parameters : baudRate - Baud rate to set
* Returns : Baud rate if successful. 0 if invalid baud rate.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
long ComWin32::BaudRate(long baudRate)
{
DWORD oldBaud = comDCB.BaudRate;
comDCB.BaudRate = (DWORD )baudRate;
if (!SetCommState(comHandle, &comDCB))
{
comLastError = GetLastError();
comDCB.BaudRate = oldBaud;
return 0;
} /* end of if */
return (long )comDCB.BaudRate;
} // ComWin32::BaudRate()
/************************************************************************
* Function name : ComWin32::BaudRate
* Description : Get baud rate.
* :
* Parameters : -
* Returns : Baud rate.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
long ComWin32::BaudRate(void)
{
return (long )comDCB.BaudRate;
} // ComWin32::BaudRate()
/************************************************************************
* Function name : ComWin32::DataLength
* Description : Set data length.
* :
* Parameters : length - Data length to set to.
* Returns : Data length if successful. 0 if failed.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
int ComWin32::DataLength(int length)
{
int oldLength = comDCB.ByteSize;
comDCB.ByteSize = length;
if (length == 5)
comDCB.StopBits = ONE5STOPBITS; // 5 bits data MUST use 1.5 stop bits
if (!SetCommState(comHandle, &comDCB))
{
comLastError = GetLastError();
comDCB.ByteSize = oldLength;
return 0;
} /* end of if */
return length;
} // ComWin32::DataLength()
/************************************************************************
* Function name : ComWin32::DataLength
* Description : Get data length.
* :
* Parameters : -
* Returns : Data length.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
int ComWin32::DataLength(void)
{
return (int )comDCB.ByteSize;
} // ComWin32::DataLength()
/************************************************************************
* Function name : ComWin32::Parity
* Description : Set up parity.
* :
* Parameters : parity - Parity to set to.
* Returns : Parity if successful. 0 if failed.
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 31Aug99 RCS Created.
************************************************************************/
char ComWin32::Parity(char parity)
{
char oldParity = comDCB.Parity;
switch (parity)
{
case 'N':
case 'n':
parity = NOPARITY;
break;
case 'E':
case 'e':
parity = EVENPARITY;
break;
case 'O':
case 'o':
parity = ODDPARITY;
break;
case 'M':
case 'm':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -