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

📄 pserialport.cpp

📁 485通讯接口模块的编程应用
💻 CPP
字号:
// PSerialPort.cpp: implementation of the CPSerialPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
 #include "PSerialPort.h"

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

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

CPSerialPort::CPSerialPort()
{
	m_hComm=INVALID_HANDLE_VALUE;
	m_hReadThread=NULL;
	m_bReceiving=FALSE;
	m_nBufferSize=256; //缓冲大小
}

CPSerialPort::~CPSerialPort()
{
	ClosePort();
}

DWORD WINAPI CPSerialPort::ReadPortThread(LPVOID lpParameter)
{
	CPSerialPort* m_pSerial;

	m_pSerial=(CPSerialPort*)lpParameter;

	BOOL fReadState;
	DWORD dwLength;
	
	char* buf=new char[m_pSerial->m_nBufferSize];

	while((m_pSerial->m_hComm!=INVALID_HANDLE_VALUE)&&(m_pSerial->m_bReceiving))
	{		
   		fReadState=ReadFile(m_pSerial->m_hComm,buf,m_pSerial->m_nBufferSize,&dwLength,NULL);
		if(!fReadState)
		{
			//AfxMessageBox(_T("无法从串口读取数据!"));
		}
		else
		{
			if(dwLength!=0)
			{
				//回送数据
				if(m_pSerial->m_lpDataArriveProc!=NULL)
				{
  					m_pSerial->m_lpDataArriveProc(buf,dwLength,m_pSerial->m_dwUserData);
				}
			}
		}		
	}

	delete[] buf;

	return 0;
}

BOOL CPSerialPort::OpenPort(LPCTSTR Port,int BaudRate,int DataBits,int StopBits,int Parity,LPDataArriveProc proc,DWORD userdata)
{
	m_lpDataArriveProc=proc;
	m_dwUserData=userdata;

	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		m_hComm=CreateFile(Port,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
		if(m_hComm==INVALID_HANDLE_VALUE )
		{
			AfxMessageBox(_T("无法打开端口!请检查是否已被占用。"));
			return FALSE;
		}
		GetCommState(m_hComm,&dcb);
		dcb.BaudRate=BaudRate;
		dcb.ByteSize=DataBits;
		dcb.Parity=Parity;
		dcb.StopBits=StopBits;
		dcb.fParity=FALSE;
		dcb.fBinary=TRUE;
		dcb.fDtrControl=0;
		dcb.fRtsControl=0;
		dcb.fOutX=dcb.fInX=dcb.fTXContinueOnXoff=0;
		
		//设置状态参数
		SetCommMask(m_hComm,EV_RXCHAR);		
		SetupComm(m_hComm,16384,16384);		
		if(!SetCommState(m_hComm,&dcb))
		{
			AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!"));
			PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
			ClosePort();
			return FALSE;
		}
		
		//设置超时参数
		GetCommTimeouts(m_hComm,&CommTimeOuts);		
		CommTimeOuts.ReadIntervalTimeout=100;
		CommTimeOuts.ReadTotalTimeoutMultiplier=1;
		CommTimeOuts.ReadTotalTimeoutConstant=100;
		CommTimeOuts.WriteTotalTimeoutMultiplier=0;
		CommTimeOuts.WriteTotalTimeoutConstant=0;		
		if(!SetCommTimeouts(m_hComm,&CommTimeOuts))
		{
			AfxMessageBox(_T("无法设置超时参数!"));
			PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
			ClosePort();
			return FALSE;
		}
		
		PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);		
		return TRUE;		
	}
	
	return FALSE;
}

BOOL CPSerialPort::ClosePort()
{
	Deactivate();
	if(m_hComm!=INVALID_HANDLE_VALUE)
	{
		SetCommMask(m_hComm,0);		
		PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
		CloseHandle(m_hComm);
		m_hComm=INVALID_HANDLE_VALUE;
		return TRUE;
	}
	
	return TRUE;	
}

BOOL CPSerialPort::Activate()
{
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	if(!m_bReceiving)
	{
		//开始接收线程
		PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
		m_bReceiving=TRUE;
		m_hReadThread=CreateThread(NULL,0,ReadPortThread,this,0,NULL);
		CloseHandle(m_hReadThread)  ; 
	}
	if(m_hReadThread!=NULL)
	{		
		return TRUE;
	}
	else
	{
		m_bReceiving=FALSE;
		return FALSE;
	}

	return FALSE;
}

BOOL CPSerialPort::Deactivate()
{
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	//停止接收线程
	if(m_bReceiving)
	{
		m_bReceiving=FALSE;
		WaitForSingleObject(m_hReadThread,500);
		CloseHandle(m_hReadThread);
		m_hReadThread=NULL;
		return TRUE;
	}

	return FALSE;
}

BOOL CPSerialPort::IsActive()
{
	return m_bReceiving;
}

DWORD CPSerialPort::WritePort(char *data,int length)
{
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		return 0;
	}

	BOOL fWriteState;
	DWORD dwBytesWritten=0;

	fWriteState=WriteFile(m_hComm,data,length*sizeof(char),&dwBytesWritten,NULL);
	
	return dwBytesWritten;
}

DWORD CPSerialPort::ReadPort(char *data,int length)
{
	BOOL fReadState;
	DWORD dwLength,dwBytesRead;
	int TimeOutCount;

	dwBytesRead=0;
	TimeOutCount=0;
	
	while(m_hComm!=INVALID_HANDLE_VALUE)
	{
		char* buf=new char[length];
		fReadState=ReadFile(m_hComm,data,length,&dwLength,NULL);
		if(!fReadState)
		{
			break;
		}
		else
		{
			dwBytesRead+=dwLength;
			data+=dwLength;			
		}
		if(dwBytesRead==length)
		{
			break;
		}
		if(dwLength!=0)
		{
			TimeOutCount=0;
		}
		else
		{
			TimeOutCount++;
			Sleep(5);
		}
		if(TimeOutCount==5)
		{
			break;
		}
	}
	return dwBytesRead;
}

DWORD CPSerialPort::WriteFileToPort(LPCTSTR FileName)
{
	if(m_hComm==INVALID_HANDLE_VALUE)
	{
		return 0;
	}

	CFile cf;

	BOOL fWriteState;
	DWORD dwBytesWritten;
	DWORD dwCharToWrite;

	dwCharToWrite=0;

	if(!cf.Open(FileName,CFile::modeRead))
	{
		//AfxMessageBox(_T("无法打开Hex文件!"));
		return 0;
	}
	dwCharToWrite=(DWORD)cf.GetLength();
	cf.Seek(0,CFile::begin);
	dwBytesWritten=0;
	
	if(m_hComm!=INVALID_HANDLE_VALUE&&dwCharToWrite!=0)
	{
		char* buf=new char[dwCharToWrite];
		cf.Read(buf,dwCharToWrite);

		fWriteState=WriteFile(m_hComm,buf,dwCharToWrite*sizeof(char),&dwBytesWritten,NULL);
		if(!fWriteState)
		{
			//AfxMessageBox(_T("无法向端口写入数据!"));
		}
		delete[] buf;		
	}
	cf.Close();
	return dwBytesWritten;
}

//读取
DWORD CPSerialPort::Read(void *pData, DWORD dwCount) const
{
	DWORD dwBytesRead = 0;
	
    ReadFile(m_hComm, pData, dwCount, &dwBytesRead, NULL);
	
    return dwBytesRead;
}

bool CPSerialPort::WaitForResponse(CString &strResponse, DWORD dwTimeout) const
{
    BOOL bData = FALSE;
	
    unsigned char cCurrentChar  = '\0';
    unsigned char cLastChar     = '\0';
    unsigned char cLastLastChar = '\0';
	
    strResponse.Empty();
    DWORD dwStartTicks = GetTickCount();
    while (TRUE)
    {
        // Has the timeout occured?
		
		if ((GetTickCount() - dwStartTicks) >= dwTimeout)
        {
			PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
     		return FALSE;
        }
		
         if (Read(&cCurrentChar, sizeof(cCurrentChar)) > 0)
        {
			
            dwStartTicks = GetTickCount();
			
			//是否是非正常字符
            if (isprint(cCurrentChar))
            {
                char szANSI[2] = { cCurrentChar, '\0' };
				
                strResponse += CString(szANSI);
            }
			else if (cCurrentChar == 0x0D)
			{
				strResponse +=_T("\r"); 
			//	TRACE(_T("%s\r\n"),strResponse)  ; 
				PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);

    		 	return TRUE ; 
			} 

			
            cLastLastChar = cLastChar;
			cLastChar     = cCurrentChar;
		   
		}
         else  Sleep(10);
            
 		
    } // while (TRUE)
	
    return TRUE;
}

⌨️ 快捷键说明

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