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

📄 comm.cpp

📁 本代码实现了类似于超级终端的功能
💻 CPP
字号:
#include "stdafx.h"
#include "comm.h"

//////////////////////////////////////////////////////////////////////////
//Serial port operation implemention
//

HANDLE m_AbortEvent;
HANDLE m_hComDev;   //串口设备句柄
OVERLAPPED m_OverlappedRead,m_OverlappedWrite;//读重叠方式
//////////////////////////////////////////////////////////////////////////
//函数名称:打开串口设备
//函数功能:打开串口,并初始化
//输入参数:
//nPort - 串口类型,如COM1,则nPort = 1
//nBaudRate-波特率
//返回值:
//成功返回TRUE,失败返回FALSE
//////////////////////////////////////////////////////////////////////////
BOOL OpenDevice(int nPort,int nBaudRate)
{
	char szPort[15];
	DCB dcb;//串口控制块

	wsprintf( szPort, "COM%d", nPort );
	//打开串口,独占方式,异步读写
	m_hComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);
	if( m_hComDev == INVALID_HANDLE_VALUE ) return( FALSE );
	
	//初始化重叠结构
	memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ));
	memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ));
	
	//超时控制
	COMMTIMEOUTS CommTimeOuts;
	CommTimeOuts.ReadIntervalTimeout = MAXDWORD ;
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
	CommTimeOuts.WriteTotalTimeoutConstant = 0;
	SetCommTimeouts( m_hComDev, &CommTimeOuts );
	
	//创建读写事件对象
	m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	
	//设置串口控制参数和缓冲区大小
	dcb.DCBlength = sizeof( DCB );
	GetCommState( m_hComDev, &dcb );
	dcb.BaudRate = nBaudRate;
	dcb.ByteSize = 8;
	dcb.StopBits = 0;
	dcb.Parity = 0;
	if( !SetCommState( m_hComDev, &dcb ) ||!SetupComm( m_hComDev, 1024, 1024 ) ||m_OverlappedRead.hEvent == NULL ||m_OverlappedWrite.hEvent == NULL )
	{
		DWORD dwError = GetLastError();
		if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
		if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
		CloseHandle( m_hComDev );
		return FALSE;
	}
	
	//m_bOpened = TRUE;
	
	return TRUE;
	
}


//////////////////////////////////////////////////////////////////////////
//函数名称:关闭串口设备
//函数功能:关闭串口,删除对象
//输入参数:无
//返回值:
//成功返回非零值
//失败返回零值
//////////////////////////////////////////////////////////////////////////
BOOL CloseDevice(void)
{
	if (m_OverlappedRead.hEvent != NULL)CloseHandle(m_OverlappedRead.hEvent);
	if (m_OverlappedWrite.hEvent != NULL)CloseHandle(m_OverlappedWrite.hEvent);
	
	return CloseHandle(m_hComDev);
}

//////////////////////////////////////////////////////////////////////////
//函数名称:读串口
//函数功能:从串口读数据到指定的内存中
//输入参数:
//pBuffer - 存放读出来的数据的缓存
//dwBytesRead -  要读的数据长度
//返回值:
//实际读的数据长度,如返回零为出错,返回-1则为中止本次操作
//////////////////////////////////////////////////////////////////////////

DWORD ReadComm(BYTE* pBuffer, DWORD dwLength )
{
	if( m_hComDev == INVALID_HANDLE_VALUE )
	{
		//句柄无效
		return 0;
	}

	BOOL bReadStatus;
	DWORD dwBytesRead ;
	DWORD dwEvent;
	HANDLE hArray[2] = { m_AbortEvent,m_OverlappedRead.hEvent};
	
	//dwRemain = dwLength;
	//读数据
		bReadStatus = ReadFile( m_hComDev, pBuffer, dwLength, &dwBytesRead, &m_OverlappedRead );
		if( !bReadStatus )
		{
			if( GetLastError() == ERROR_IO_PENDING )
			{
				//读操作未完成
				//WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );

				//等待事件对象变成信号量
				dwEvent = WaitForMultipleObjects(2,hArray,FALSE,INFINITE);
				if (dwEvent == WAIT_OBJECT_0)
				{
					//用户中止读操作
					return -1;	
				}
				else if(dwEvent = (WAIT_OBJECT_0 +1))
				{
					//读操作完成
					//bReadStatus = GetOverlappedResult(m_hComDev,&m_OverlappedRead,&dwBytesRead,FALSE);
					ResetEvent(m_OverlappedRead.hEvent);
				}
				else
				{
					//出错
					return 0;
				}//else
			
			}
			else
			{
				//出错
				return 0;
			}//else
		}
		else
		{	
			//读操作立即完成
			ResetEvent(m_OverlappedRead.hEvent);
			
		}//else
	
	return dwLength;

}


//////////////////////////////////////////////////////////////////////////
//函数名称:写串口
//函数功能:从内存写数据到串口,同步方式
//输入参数:
//pBuffer - 数据缓冲区
//dwLength - 数据长度
//返回值:
//实际读的数据长度,如返回零为出错,返回-1则为中止本次操作
//////////////////////////////////////////////////////////////////////////
DWORD WriteComm(BYTE* pBuffer, DWORD dwLength)
{
	if (m_hComDev == INVALID_HANDLE_VALUE)
	{
		//句柄无效
		return 0;
	}

	BOOL bWriteStatus;
	DWORD dwRemain,dwBytesWritten;
	DWORD dwEvent;
	HANDLE hArray[2] = { m_AbortEvent,m_OverlappedWrite.hEvent};


	dwRemain = dwLength;
	//写数据
	while (dwRemain)
	{	
		bWriteStatus = WriteFile( m_hComDev, pBuffer, dwRemain, &dwBytesWritten, &m_OverlappedWrite );
		if( !bWriteStatus)
		{
			if( GetLastError() == ERROR_IO_PENDING )
			{
				//写操作未完成
				
				//等待对象变成信号量
				dwEvent = WaitForMultipleObjects(2,hArray,FALSE,INFINITE);
				if (dwEvent == WAIT_OBJECT_0)
				{
					//用户中止读操作
					return -1;	
				}
				else if (dwEvent == (WAIT_OBJECT_0 +1))
				{
					//写操作完成
					bWriteStatus = GetOverlappedResult(m_hComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
					pBuffer += dwBytesWritten;
					dwRemain -= dwBytesWritten;
					ResetEvent(m_OverlappedWrite.hEvent);
				}
				else
				{
					//出错
					return 0 ;
				}//else
			}
			else
			{
				//出错
				return 0;
			}//else
		}
		else
		{
			//写操作完成
			bWriteStatus = GetOverlappedResult(m_hComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
			dwRemain -= dwBytesWritten;
			ResetEvent(m_OverlappedWrite.hEvent);
		}//else
		
	}//while	
	return dwLength;
}

⌨️ 快捷键说明

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