📄 serialport.cpp
字号:
#include "StdAfx.h"
#include ".\serialport.h"
#include <cassert>
CSerialPort::CSerialPort(void)
: m_bOpen(false)
{
::ZeroMemory(&m_Dcb,sizeof(m_Dcb));
m_Dcb.DCBlength = sizeof(m_Dcb);
m_hCommu = INVALID_HANDLE_VALUE;
m_nBufferIn = m_nBufferOut = 512;
::ZeroMemory(&m_nTimeOut,sizeof(m_nTimeOut));
m_nTimeOut.ReadIntervalTimeout = 100;
m_nTimeOut.ReadTotalTimeoutMultiplier = 150;
m_nTimeOut.WriteTotalTimeoutConstant = 1000;
m_nTimeOut.WriteTotalTimeoutMultiplier = 1000;
m_nTimeOut.WriteTotalTimeoutConstant = 1000;
::ZeroMemory(&m_OvlpWrite,sizeof(m_OvlpWrite));
m_OvlpWrite.hEvent = CreateEvent(NULL, true, false, NULL);
assert(m_OvlpWrite.hEvent != INVALID_HANDLE_VALUE);
::ZeroMemory(&m_OvlpRead,sizeof(m_OvlpRead));
m_OvlpRead.hEvent = CreateEvent(NULL,true,false,NULL);
}
CSerialPort::~CSerialPort(void)
{
if(m_bOpen) Close();
}
void CSerialPort::Init(void)
{
}
void CSerialPort::Close(void)
{
if(m_bOpen)
::CloseHandle(m_hCommu);
m_bOpen = false;
m_hCommu = INVALID_HANDLE_VALUE;
::ResetEvent(m_OvlpWrite.hEvent);
::CloseHandle(m_OvlpWrite.hEvent);
::ResetEvent(m_OvlpRead.hEvent);
::CloseHandle(m_OvlpRead.hEvent);
}
bool CSerialPort::Open(UINT nPort,DWORD BaudRate,
BYTE ByteSize,BYTE Parity, BYTE StopBits)
{
m_nPort = nPort;
if(m_bOpen) Close();
char com_str[10];
strcpy(com_str, "COM");
ltoa(m_nPort, com_str + 3, 10);
m_hCommu = CreateFile(
com_str,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠I/O
NULL
);
if(m_hCommu == INVALID_HANDLE_VALUE) return false;
BOOL tempBit;
//----------------------------------------------------------------------
//设置缓冲区
tempBit = SetupComm(m_hCommu,m_nBufferIn,m_nBufferOut);
if(!tempBit) return false;
//-----------------------------------------------------------------------
//设置串口参数:波特率,数据位......等等
tempBit = GetCommState(m_hCommu,&m_Dcb);
if(!tempBit) return false;
m_Dcb.BaudRate = BaudRate;
m_Dcb.ByteSize = ByteSize;
m_Dcb.Parity = NOPARITY;//MODBUS的特殊需要
m_Dcb.StopBits = StopBits;
tempBit = SetCommState(m_hCommu,&m_Dcb);
if(!tempBit) return false;
//------------------------------------------------------------------------------
//设置超时时间
tempBit = SetCommTimeouts(m_hCommu, &m_nTimeOut);
if(!tempBit) return false;
//--------------------------------------------------------------------------------
//清空串口缓冲区
tempBit = PurgeComm(m_hCommu,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
if(!tempBit) return false;
//-----------------------------------------------------------------------------------
m_bOpen = true;
return true;
}
//用于多机通信
bool CSerialPort::SetParityBit(BYTE nParity)
{
m_Dcb.Parity = nParity;
if(SetCommState(m_hCommu,&m_Dcb)) return true;
return false;
}
//在开串口之前调用有效
void CSerialPort::InitBufferSize(UINT nBufferIn, UINT nBufferOut)
{
m_nBufferIn = nBufferIn;
m_nBufferOut = nBufferOut;
}
//异步写数据
bool CSerialPort::WriteData(BYTE* pWriteBuff, WORD nWrite)
{
if(!m_bOpen) return false;
assert(pWriteBuff);
m_OvlpWrite.Offset = 0;
m_OvlpWrite.OffsetHigh = 0;
DWORD dwError;
COMSTAT state;
::ClearCommError(m_hCommu,&dwError,&state);//清除错误标志
PurgeComm(m_hCommu, PURGE_TXABORT | PURGE_TXCLEAR
|PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓冲区和终止发送与接收
DWORD nRealWrite = 0;
BOOL bResult;
bool bWrite = true;
bResult = WriteFile(m_hCommu,pWriteBuff,nWrite,&nRealWrite,&m_OvlpWrite);//异步写
if(!bResult)
{
dwError = ::GetLastError();
switch(dwError)
{
case ERROR_IO_PENDING:
{
bWrite = false;
break;
}
default:return false;
}
}
if(!bWrite)
{
bResult = ::GetOverlappedResult(m_hCommu,&m_OvlpWrite,&nRealWrite,true);
if(!bResult) return false;
bWrite = true;
}
return true;
}
//异步读数据
DWORD CSerialPort::ReadData(BYTE* pReadBuff, WORD nRead)
{
COMSTAT state;
BOOL bResult;
DWORD dwError = 0;
DWORD nRealRead = 0;
bool bRead = true;
::ClearCommError(m_hCommu,&dwError,&state);
bResult = ::ReadFile(m_hCommu,pReadBuff,nRead,&nRealRead,&m_OvlpRead);
if(!bResult)
{
dwError = ::GetLastError();
switch(dwError)
{
case ERROR_IO_PENDING:
{
bRead = false;
break;
}
default:return false;
}
}
if(!bRead)
{
bResult = ::GetOverlappedResult(m_hCommu,&m_OvlpRead,&nRealRead,true);
if(!bResult) return false;
bRead = true;
}
return nRealRead;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -