⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cpp

📁 用Win32API建立的一个串口通信类,侧重于异步通信方式,做用来做串口通信很方便.
💻 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 + -