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

📄 serialport.cpp

📁 自己开发的
💻 CPP
字号:
// SerialPort.cpp: implementation of the CSerialPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SerialPort.h"

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


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

CSerialPort::CSerialPort()
{
	m_bConnected = FALSE;
	m_hPort = NULL;

	sprintf(m_PortConfig.szPortName,"COM1\0");
	m_PortConfig.BaudRate = 4800;
	m_PortConfig.ByteSize = 8;
	m_PortConfig.Parity = 0;
	m_PortConfig.StopBits = 0;
	m_PortConfig.Flow = 1;

	memset(&m_RdOverlapped,0,sizeof(OVERLAPPED));
	m_RdOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

	memset(&m_WtOverlapped,0,sizeof(OVERLAPPED));
	m_WtOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

}

CSerialPort::~CSerialPort()
{
	DisconnectPort();
	
	if(m_RdOverlapped.hEvent!=NULL)
	{
		CloseHandle(m_RdOverlapped.hEvent);
		m_RdOverlapped.hEvent = NULL;
	}

	if(m_WtOverlapped.hEvent!=NULL)
	{
		CloseHandle(m_WtOverlapped.hEvent);
		m_WtOverlapped.hEvent = NULL;
	}
	
}

BOOL CSerialPort::ConnectionPort(tagPortParam *pPortConfig)
{
    DCB dcb;
    
    BOOL bSuccess;
	
	if(m_hPort!=NULL)
		return FALSE;

	if(pPortConfig==NULL)
		pPortConfig = &m_PortConfig;
	else
		memcpy(&m_PortConfig,pPortConfig,sizeof(tagPortParam));

	m_hPort = CreateFile(m_PortConfig.szPortName,
					GENERIC_READ | GENERIC_WRITE,
					0,    
					NULL, 
					OPEN_EXISTING, 
					FILE_FLAG_OVERLAPPED,   
					NULL);
				
	
	if (m_hPort == INVALID_HANDLE_VALUE) 
	{
		CString strInfo;
		strInfo.Format("CreateFile failed with error %d.\n", GetLastError());
		AfxMessageBox(strInfo);
		return FALSE;
	}
	
	bSuccess = GetCommState(m_hPort, &dcb);
	if (!bSuccess) 
	{
		CString strInfo;
		strInfo.Format("GetCommState failed with error %d.\n", GetLastError());
		AfxMessageBox(strInfo);
		return FALSE;
	}
	
	// Fill in the DCB
	dcb.BaudRate = pPortConfig->BaudRate;
	dcb.ByteSize = pPortConfig->ByteSize;
	dcb.Parity = pPortConfig->Parity;
	dcb.StopBits = pPortConfig->StopBits;
	switch(pPortConfig->Flow) 
	{
	case 0: dcb.fOutX=FALSE;	dcb.fInX=FALSE;	
			dcb.fOutxCtsFlow=FALSE;	dcb.fOutxDsrFlow=FALSE;
			dcb.fDtrControl=DTR_CONTROL_DISABLE;
			dcb.fRtsControl=RTS_CONTROL_DISABLE;
			break;
	case 1: dcb.fOutX=TRUE;	dcb.fInX=TRUE;	
			dcb.fOutxCtsFlow=FALSE;	dcb.fOutxDsrFlow=FALSE;
			dcb.fDtrControl=DTR_CONTROL_DISABLE;
			dcb.fRtsControl=RTS_CONTROL_DISABLE;
			break;
	case 2: dcb.fOutX=FALSE;	dcb.fInX=FALSE;	
			dcb.fOutxCtsFlow=TRUE;	dcb.fOutxDsrFlow=TRUE;
			dcb.fDtrControl=DTR_CONTROL_ENABLE;
			dcb.fRtsControl=RTS_CONTROL_ENABLE;
			break;
	}


	
	bSuccess = SetCommState(m_hPort, &dcb);
	if (!bSuccess) 
	{
		CString strInfo;
		strInfo.Format("SetCommState failed with error %d.\n", GetLastError());
		AfxMessageBox(strInfo);
		return FALSE;
	}

	m_bConnected = TRUE;

	return TRUE;
}

BOOL CSerialPort::DisconnectPort()
{

	Sleep(500);
	
	if(m_hPort!=NULL)
	{
		CloseHandle(m_hPort);
		m_hPort = NULL;
	}
	
	m_bConnected = FALSE;
	return TRUE;
}


BOOL CSerialPort::IsConnected()
{
	return  m_bConnected;
}

/*
DWORD CSerialPort::ReadPortData(LPSTR lpszPortData, int nMaxLen, OVERLAPPED *pOverlapped)
{
	BOOL 	  bResult;
	
	COMSTAT	  ComStat ;
	DWORD	  dwErrorFlags;
	DWORD	  dwLength;
	DWORD	  dwError;

	ClearCommError(m_hPort, &dwErrorFlags, &ComStat ) ;
	dwLength = min((DWORD) nMaxLen,ComStat.cbInQue ) ;
	
	if(dwLength > 0)
	{
		bResult = ReadFile(m_hPort,lpszPortData,dwLength,&dwLength,pOverlapped);

		if(!bResult&&pOverlapped!=NULL)
		{
			if(GetLastError()==ERROR_IO_PENDING)
			{
				while(!GetOverlappedResult(m_hPort,pOverlapped,&dwLength,TRUE))
				{
					dwError = GetLastError();
					if(dwError == ERROR_IO_INCOMPLETE)
						continue;
				}
			}
			else
			{
				dwLength = 0;
				ClearCommError(m_hPort,&dwErrorFlags,&ComStat);
			}
		}
	}

	return(dwLength);
}

int CSerialPort::WritePortData(LPSTR lpszBuf, DWORD dwWriteLen)
{
	BOOL        bResult ;
	DWORD		dwBytesToWrite;
	DWORD       dwBytesWritten = 0;
	DWORD       dwErrorFlags;
	DWORD   	dwError;
	DWORD       dwBytesSent = 0;
	COMSTAT     ComStat;
	char        szError[128] ;
	
	LPSTR lpSendBuf = new char[dwWriteLen+5];
	memcpy(lpSendBuf,lpszBuf,dwWriteLen);

	dwBytesToWrite = dwWriteLen;

	bResult = WriteFile(m_hPort,lpSendBuf,dwBytesToWrite,&dwBytesWritten,&(m_WtOverlapped));
	
	if (!bResult)
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			for(int i=0;i<3;i++)
			{
				if(GetOverlappedResult(m_hPort,&(m_WtOverlapped),&dwBytesWritten,FALSE))
					break;

				dwError = GetLastError();
				if(dwError==ERROR_IO_INCOMPLETE)
				{
					// normal result if not finished
					dwBytesSent += dwBytesWritten;
					Sleep(50);
					continue;
				}
				else
				{
					ClearCommError(m_hPort,&dwErrorFlags,&ComStat);
					break;
				}
			}
			
			dwBytesSent += dwBytesWritten;
			
			if( dwBytesSent != dwBytesToWrite )
			{	
				sprintf(szError,"\nProbable Write Timeout: Total of %ld bytes sent", dwBytesSent);
				AfxMessageBox(szError);
			}
		}
		else
		{
			ClearCommError(m_hPort,&dwErrorFlags,&ComStat) ;
			delete []lpSendBuf;
//			AfxMessageBox("Write date error");
			return(FALSE);
		}
	}
	delete []lpSendBuf;
	return dwBytesWritten;	
}
*/

BOOL CSerialPort::WritePortData(CString strCmd)
{
	char szBuffer[256];
	sprintf(szBuffer,"%s\0",strCmd);
	BOOL bResult = WritePortData(szBuffer,strCmd.GetLength());
	return bResult;
}



//异步读数据
unsigned long CSerialPort::ReadPortData(char *buff,unsigned long dwBufferLength)
{   
	unsigned long dwWaitTime=1000;
	if(!IsConnected())  
		return(0);   
		
	DWORD		dwError;
	COMSTAT		Stat;  
	if(::ClearCommError(m_hPort, &dwError, &Stat) && dwError > 0)	//清除错误
	{
		::PurgeComm(m_hPort, PURGE_RXABORT | PURGE_RXCLEAR); /*清除输入缓冲区*/
		return 0;
	}
	if(!Stat.cbInQue)// 缓冲区无数据
	{
		return 0;
	}

	unsigned long uReadLength = 0;
	dwBufferLength = dwBufferLength - 1 > Stat.cbInQue ? Stat.cbInQue : dwBufferLength - 1;
	if(!::ReadFile(m_hPort, buff, dwBufferLength, &uReadLength, &m_RdOverlapped)) //2000 下 ReadFile 始终返回 True
	{
		if(::GetLastError() == ERROR_IO_PENDING) // 结束异步I/O
		{
			WaitForSingleObject(m_RdOverlapped.hEvent, dwWaitTime);	//等待20ms
			if(!::GetOverlappedResult(m_hPort, &m_RdOverlapped, &uReadLength, false))
			{
				if(::GetLastError() != ERROR_IO_INCOMPLETE)//其他错误
				{
					uReadLength = 0;
				}
			}
		}
		else
		{
			uReadLength = 0;
		}
	}
		
	return uReadLength;
}


//异步写数据 
unsigned long CSerialPort::WritePortData(char *buff,unsigned long dwBufferLength )
{
	if(!IsConnected())
	{
		return 0;
	}

	DWORD dwError;
	if(ClearCommError(m_hPort, &dwError, NULL) && dwError > 0)	//清除错误
	{
		PurgeComm(m_hPort, PURGE_TXABORT | PURGE_TXCLEAR);	
	}

	unsigned long uWriteLength = 0;
	if(!WriteFile(m_hPort, buff, dwBufferLength, &uWriteLength, &m_WtOverlapped))
	{
		if(GetLastError() == ERROR_IO_PENDING)
		{
			DWORD m_tmp=0;
			m_tmp= WaitForSingleObject(m_WtOverlapped.hEvent, 1000);
			if(m_tmp== WAIT_TIMEOUT || m_tmp== WAIT_ABANDONED)
			{
				return(0);
			}
			else if(m_tmp== WAIT_OBJECT_0)
			{			
				if(!GetOverlappedResult(m_hPort,&m_WtOverlapped,&uWriteLength,false))
				{
					return(0);		
				}
				else
				{
					return uWriteLength;		
				}
			}
			
			uWriteLength = 0;
		}
	}

	return uWriteLength;  
}

⌨️ 快捷键说明

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