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

📄 serial.cpp

📁 自己写得串口多线程控制程序
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Serial.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerial::CSerial()
{
	m_hCom = 0;

	memset(&m_writeov,0,sizeof(OVERLAPPED));
	memset(&m_readov,0, sizeof(OVERLAPPED));
	memset(&m_waitov,0,sizeof(OVERLAPPED));

	memset(&m_comstat,0,sizeof(COMSTAT));
	memset(&m_commtimeouts,0,sizeof(COMMTIMEOUTS));
	memset(&dcb,0,sizeof(DCB));
}

CSerial::~CSerial()
{
	Close();
}

BOOL CSerial::Open(LPCSTR lpszPortNum , DWORD dwBaudRate, BYTE byParity, BYTE byStopBits, BYTE byByteSize)
{
	BOOL bSuccess=TRUE;

	m_readov.hEvent = CreateEvent(NULL , TRUE , FALSE , TOKENREADNAME);//TRUE--设置自动重置信号事件
	if(m_readov.hEvent==INVALID_HANDLE_VALUE)
		return FALSE;

	m_writeov.hEvent = CreateEvent(NULL , TRUE , FALSE , TOKENWRITENAME);
	if(m_writeov.hEvent==INVALID_HANDLE_VALUE)
		return FALSE;

	m_waitov.hEvent = CreateEvent(NULL , FALSE , FALSE , TOKENWAITNAME);//FALSE- -设置自动重置信号事件
	if(m_waitov.hEvent==INVALID_HANDLE_VALUE)
		return FALSE;

	m_hCom = CreateFile(lpszPortNum , 
						GENERIC_READ|GENERIC_WRITE ,
						0 ,
						NULL ,
						OPEN_EXISTING ,
						FILE_FLAG_OVERLAPPED ,
						NULL);
	if(m_hCom == INVALID_HANDLE_VALUE)
	{
		CSerial::Close();
		return FALSE;
	}

	//Omit the call to SetupComm to use the default queue sizes.Get the current configuration.
	bSuccess = GetCommState(m_hCom , &dcb);
	if(!bSuccess)
	{
		CSerial::Close();
		return FALSE;
	}

	//Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit are default parameters
	dcb.DCBlength = sizeof(DCB);
	dcb.BaudRate = dwBaudRate;
	dcb.ByteSize = byByteSize;
	dcb.Parity = byParity;
	dcb.StopBits = byStopBits;

	bSuccess = SetCommState(m_hCom , &dcb);
	if(!bSuccess)
	{
		CSerial::Close();
		return FALSE;
	}

	m_commtimeouts.ReadIntervalTimeout=MAXDWORD;
	m_commtimeouts.ReadTotalTimeoutConstant=0;
	m_commtimeouts.ReadTotalTimeoutMultiplier=0;
	m_commtimeouts.WriteTotalTimeoutConstant=3;
	m_commtimeouts.WriteTotalTimeoutMultiplier=1;
	bSuccess = SetCommTimeouts(m_hCom, &m_commtimeouts);
	if(!bSuccess)
	{
		CSerial::Close();
		return FALSE;
	}

	bSuccess = SetupComm(m_hCom, 1500, 1500);
	if(!bSuccess)
	{
		CSerial::Close();
		return FALSE;
	}

	bSuccess = PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

	//设置串口监听事件
	bSuccess=SetCommMask(m_hCom ,EV_RXCHAR);
	if(!bSuccess)
	{
		CloseHandle(m_hCom);
		return FALSE;
	}

	DWORD  dwErrorFlags=0;
	bSuccess = ClearCommError(m_hCom, &dwErrorFlags, &m_comstat);
	if(!bSuccess)
	{
		CSerial::Close();
		return FALSE;
	}
	return TRUE;
}

void CSerial::Close()
{
	if(m_readov.hEvent!=INVALID_HANDLE_VALUE&&m_readov.hEvent!=0)
	{
		CloseHandle(m_readov.hEvent);
		m_readov.hEvent=0;
	}
	if(m_writeov.hEvent!=INVALID_HANDLE_VALUE&&m_writeov.hEvent!=0)
	{
		CloseHandle(m_writeov.hEvent);
		m_writeov.hEvent=0;
	}
	if(m_waitov.hEvent!=INVALID_HANDLE_VALUE&&m_waitov.hEvent!=0)
	{
		CloseHandle(m_waitov.hEvent);
		m_waitov.hEvent=0;
	}

	if(m_hCom!=INVALID_HANDLE_VALUE&&m_hCom!=0)
	{
		CloseHandle(m_hCom);
		m_hCom=0;
	}
}

/*
DWORD CSerial::WriteData(const UCHAR* pData , DWORD nLen ,const char* cShow)
{
	if(nLen<1)
		return 0;

	DWORD write=0;

	TRACE("\nWrite^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);

	if(!WriteFile(m_hCom, pData, nLen, &write, &m_writeov))
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			if(!GetOverlappedResult(m_hCom, &m_writeov, &write, FALSE))
			{
				if(GetLastError()==ERROR_IO_INCOMPLETE)
				{
WRITEWAIT:
					switch(WaitForSingleObject(m_writeov.hEvent,nLen*1))
					{
					case WAIT_OBJECT_0:
						TRACE("\nWRITE WAIT_OBJECT_0^write:%d",write);
						break;
					case WAIT_TIMEOUT:
						TRACE("\nWRITE WAIT_TIMEOUT^write:%d",write);
						goto WRITEWAIT;
						//CancelIo(m_hCom);//???是否将读写缓冲区清空???
						break;
					default:
						TRACE("\nWRITE default^write:%d",write);
						break;
					}
				}
			}
		}
	}

	ResetEvent(m_writeov.hEvent);
	TRACE("\nWRITEEND^write:%d",write);
	return write;
	}
*/

BOOL CSerial::WaitData(DWORD& mask, const char *cShow)
{
//	TRACE("\nm_waitov.hEvent:%x",m_waitov.hEvent);
//	TRACE("\nWAIT^m_hCom:%x",m_hCom);
	if(!WaitCommEvent(m_hCom , &mask , &m_waitov))
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{	
			//此处必须设置等待时间为无限长,才能阻塞串口
			switch(WaitForSingleObject(m_waitov.hEvent,1000))
		//	switch(WaitForSingleObject(m_waitov.hEvent,INFINITE))
			{
			case WAIT_OBJECT_0:
//				TRACE("\nWAIT^WAIT_OBJECT_0");
				break;
			case WAIT_TIMEOUT:
				ClearError();
				//CancelIo(m_hCom);
//				TRACE("\nWAIT^WAIT_TIMEOUT");
				break;
			default:
//				TRACE("\nWAIT^default");
				break;
			}
		}
	}
	return true;
}

DWORD CSerial::WriteData(const UCHAR* pData , DWORD nLen, const char* cShow)
{
	if(nLen<1)
		return 0;
	
	DWORD write=0;
	TRACE("\nWRITEBEGIN^nLen:%d",nLen);
	//TRACE("\nWrite^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);
	
	if(!WriteFile(m_hCom, pData, nLen, &write, &m_writeov))
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			GetOverlappedResult(m_hCom, &m_writeov, &write, TRUE);
		}//end last error == io pending
	} //end readfile 
	
	ResetEvent(m_writeov.hEvent);

	TRACE("\nWRITEEND^write:%d",write);
	return write;
}

DWORD CSerial::ReadData(UCHAR* pData, DWORD nLen,const char* cShow)
{
	if(nLen<1)
		return 0;

	DWORD read=0;
	//TRACE("\nRead^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);

	if(!ReadFile(m_hCom, pData, nLen, &read, &m_readov))
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			if(!GetOverlappedResult(m_hCom, &m_readov, &read, FALSE))
			{
				if(GetLastError()==ERROR_IO_INCOMPLETE)
				{
READWAIT:
					switch(WaitForSingleObject(m_readov.hEvent,nLen*1))
					{
					case WAIT_OBJECT_0:
//						TRACE("\nREAD WAIT_OBJECT_0^read:%d",read);
						break;
					case WAIT_TIMEOUT:
//						TRACE("\nREAD WAIT_TIMEOUT^read:%d",read);
						//CancelIo(m_hCom);//???是否将读写缓冲区清空???
						goto READWAIT;
						break;
					default:
//						TRACE("\nREAD default^read:%d",read);
						break;
					}
				}
			}
		}
	}

	ResetEvent(m_readov.hEvent);
//	TRACE("\nREADEND^%s^read:%d",cShow,read);
	return read;
}


/*DWORD CSerial::ReadData(UCHAR* pData, DWORD nLen)
{
	if(nLen<1)
		return 0;
	
	DWORD read=0;
	
	if(!ReadFile(m_hCom, pData, nLen, &read, &m_readov))
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			GetOverlappedResult(m_hCom, &m_readov, &read, FALSE);
		}
	}
	ResetEvent(m_readov.hEvent);
	return read;
}
*/

BOOL CSerial::ClearError(const char* cShow)
{
	DWORD  dwErrorFlags=0;
	BOOL bSuccess=ClearCommError(m_hCom, &dwErrorFlags, &m_comstat);
//	TRACE("\n%s^IN:%d^OUT:%d^bSuccess:%d",cShow,m_comstat.cbInQue,m_comstat.cbOutQue,bSuccess);
	return bSuccess;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -