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

📄 asynccom.cpp

📁 vc 485串口通讯测试程序 vc-commtest
💻 CPP
字号:
// ComModem.cpp: implementation of the CAsyncCom class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AsyncCom.h"
#include <direct.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//MODEM拨号的状态
#define MODEM_CORRECT_EXECUTE                0 //
#define MODEM_INVIALID_ATCOM                 1 //
#define MODEM_CONNECTED                      2 //
#define MODEM_CARRIER                        3 //
#define MODEM_NOCARRIER                      4 //
#define MODEM_BUSY                           5 //
#define MODEM_RING                           6 //
#define MODEM_NODIALONE                      7 //
#define MODEM_UNKNOW_RETURN                  10 //

//#define EVENT_RECEIVE                        1   // 收到数据
//#define EVENT_SEND                           2   // 发送数据
//#define EVENT_ERROR                          3   // 错误

DWORD WINAPI ThreadWatchComm(LPVOID pParm);
//DWORD WINAPI ThreadTest(LPVOID pParm);
/*
功  能:重叠操作处理线程
设计者:
时  间:2001-5
函数名:ThreadWatchComm(LPVOID pParm)
参  数:   pParm:CAsyncCom的实例句柄
*/
DWORD WINAPI ThreadWatchComm(LPVOID pParm)
{
	CAsyncCom * pCom = (CAsyncCom*)pParm;
	DWORD dwTransfer,dwEvtMask;
//	DWORD retrycount;
//	DWORD errcode;
	COMSTAT stat;
	
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	DWORD err;
	if(!SetCommMask(pCom->hComDev,EV_RXCHAR|EV_TXEMPTY|EV_ERR|EV_RLSD)) //|EV_ERR
		return FALSE;
	while(!pCom->ThreadExit)
	{
		dwEvtMask = 0;
		dwTransfer = 0;
		if(!WaitCommEvent(pCom->hComDev,&dwEvtMask,&pCom->os))
		{
			err = GetLastError();
			if(ERROR_IO_PENDING == err)				
			{
				GetOverlappedResult(pCom->hComDev,&pCom->os,&dwTransfer,0);
			}
			else
			{
				ClearCommError(pCom->hComDev,&err,&stat);
				Sleep(100);
				continue;
			}
		}
		if(!pCom->ProcEventFlags)
		{
			Sleep(50);
			continue;
		}
//		if((dwEvtMask & EV_RXCHAR)==EV_RXCHAR)//收到字符
		{
//			Sleep(50);
			if(ComStat.cbInQue > 0)
			{
				pCom->ProcessEvent(EV_RXCHAR,0);
			}
			ClearCommError(pCom->hComDev,&dwErrorFlags,&ComStat);
		}
		if((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)//发送字符
			pCom->ProcessEvent(EV_TXEMPTY,0);
		if((dwEvtMask & EV_RLSD) == EV_RLSD)//DCD信号改变状态
			pCom->ProcessEvent(EV_RLSD,0);
		if((dwEvtMask & EV_ERR) == EV_ERR)//线路错误
		{
			err = GetLastError();
			pCom->ProcessEvent(EV_ERR,err);
		}
	}
	ExitThread(0);
	return 0;
}

//##ModelId=3BDCCE3E004E
CAsyncCom::CAsyncCom()
{
	m_reqthreadexitcount = 0;
	ThreadExit = TRUE;
	ConnMethod = CONNMETOD_COM;
	IsOpen = FALSE;
	ProcEventFlags = TRUE;
//	postRecvEvent = NULL;
	read_os.hEvent  = NULL;
//	postSendEvent = NULL;
	write_os.hEvent = NULL;
	os.hEvent = NULL;
	hThreadWatchComm = NULL;
}

//##ModelId=3BDCCE3E0057
CAsyncCom::~CAsyncCom()
{

}

//##ModelId=3B2864BA0195
/*
功能:打开串口的操作
设计者:
*/
//##ModelId=3BDCCE3E004D
CAsyncCom::Open()
{
	m_reqthreadexitcount = 0;
	int comMask,comBuf,comState;
	COMMTIMEOUTS  CommTimeOuts;
	DCB dcb;
	hComDev = CreateFile(sComName,
						GENERIC_READ|GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//
						NULL);
	if(hComDev == (HANDLE)-1)
	{
		OnError(GetLastError());
		return 0;
	}
	IsOpen = TRUE;
	DWORD dwTemp;
//	if(BaudRate>0)
//		dwTemp = 1000 / (BaudRate / 8);
//	else
	dwTemp = 0;
	CommTimeOuts.ReadIntervalTimeout = 0xffffffff;
	CommTimeOuts.ReadTotalTimeoutMultiplier = ((dwTemp > 0) ? dwTemp : 1);
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	if(BaudRate == 0)
		CommTimeOuts.WriteTotalTimeoutMultiplier = 1;
	else
		CommTimeOuts.WriteTotalTimeoutMultiplier = 2*CBR_9600/BaudRate;//( npTTYInfo ) ;
	CommTimeOuts.WriteTotalTimeoutConstant = 1000;//1000;
	SetCommTimeouts( hComDev, &CommTimeOuts);

	SetCommMask(hComDev, EV_RXCHAR);
    
	PurgeComm( hComDev, PURGE_TXCLEAR | PURGE_RXCLEAR ) ;

	comMask = SetCommMask(hComDev,EV_RXFLAG);
	comBuf = SetupComm(hComDev,4096,4096);
	comState = GetCommState(hComDev,&dcb);

	dcb.BaudRate = BaudRate;//CBR_19200
	dcb.ByteSize = ByteSize;//8
	switch(Parity)
	{
	case 0:
		dcb.Parity = NOPARITY;//NOPARITY;
		break;
	case 1:
		dcb.Parity = ODDPARITY;
		break;
	case 2:
		dcb.Parity = EVENPARITY;
		break;
	}	
	switch(StopBits)
	{
	case 1:
		dcb.StopBits = ONESTOPBIT;
		break;
	case 2:
		dcb.StopBits = TWOSTOPBITS;
		break;
	default:
		dcb.StopBits = 1;
		break;
	}

	dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
	dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
	
	dcb.fBinary = 1;
	dcb.fParity = 1;
/*	dcb.fErrorChar = 0;
	dcb.ErrorChar = 0;
	dcb.EvtChar = 0;
	dcb.fOutxDsrFlow = 0;
	dcb.fOutxDsrFlow = 0;
	dcb.fInX = 0;
	dcb.fOutX = 0;
	dcb.XonChar = 17 ;
	dcb.XoffChar = 19 ;
	dcb.XonLim = 2048 ;
	dcb.XoffLim = 512 ;
	dcb.fDsrSensitivity = 0;
	dcb.fTXContinueOnXoff = 0;//
	dcb.fNull = 0;//
	dcb.fAbortOnError = 0;//
*/
	comState = SetCommState(hComDev,&dcb);
	InitEvent();

	InitThread();//启动线程控制重叠操作
	return 1;
}

//##ModelId=3B2864BA0146
/*
功能:关闭串口的操作
设计者:
*/
//##ModelId=3BDCCE3E0011
CAsyncCom::Close()
{	
	ThreadExit = TRUE;
	CloseEvent();
	if(hComDev)
	{
		CloseHandle(hComDev);
		hComDev = NULL;
		IsOpen = FALSE;
	}
	CloseThread();	
}

//##ModelId=3B2864BA01BD
/*
  功能:初始化重叠操作
  设计者:
*/
//##ModelId=3BDCCE3E0076
CAsyncCom::InitEvent()
{
	memset(&read_os,0,sizeof(OVERLAPPED));
	read_os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
	
	memset(&write_os,0,sizeof(OVERLAPPED));
	write_os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);

	memset(&os,0,sizeof(OVERLAPPED));
	os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
	return 1;
}

//##ModelId=3BDCCE3E0075
CAsyncCom::InitThread()
{
	ThreadExit = FALSE;
	hThreadWatchComm = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadWatchComm,(LPVOID)this,0,&Thread_TimeOut_id);
	return 1;
}

//##ModelId=3BDCCE3E0061
CAsyncCom::CloseEvent()
{
	if(read_os.hEvent)
		CloseHandle(read_os.hEvent);
	if(write_os.hEvent)
		CloseHandle(write_os.hEvent);
	if(os.hEvent)
		CloseHandle(os.hEvent);
	read_os.hEvent = NULL;
	write_os.hEvent = NULL;	
	os.hEvent = NULL;
}

//##ModelId=3BDCCE3E006B
CAsyncCom::CloseThread()
{
	DWORD ExitCode = 1;
	if(hThreadWatchComm)
	{	
		ThreadExit = 1;
/*		if(m_reqthreadexitcount == 3)
		{
			::TerminateThread(hThreadWatchComm,&ExitCode);
			hThreadWatchComm = NULL;
			return 1;
		}
		else
		{
			if(::WaitForSingleObject(hThreadWatchComm,100)==WAIT_TIMEOUT)
			{
				m_reqthreadexitcount ++;
				return 0;
			}
			else
			{
				CloseHandle(hThreadWatchComm);
				hThreadWatchComm = NULL;
				return 1;
			}
		}
*/
		if(::WaitForSingleObject(hThreadWatchComm,500)==WAIT_TIMEOUT)
		{
			::TerminateThread(hThreadWatchComm,ExitCode);
		}
		CloseHandle(hThreadWatchComm);
		hThreadWatchComm = NULL;
		return 1;
	}
	return 1;
}

//##ModelId=3BDCCE3D03E7
CAsyncCom::OnError(DWORD err)
{
	DWORD err1;
	COMSTAT stat;
	ClearCommError(hComDev,&err1,&stat);
}


//##ModelId=3B2864BA0128
/*
功  能:数据发送函数,调用此函数发送数据缓冲区的数据
设计者:
时  间:2001-5
函数名:Write(BYTE *buff, DWORD bufflen,BOOL bOver)
参  数:   BYTE *buff             发送数据缓冲区
          DWORD bufflen          请求发送数据长度
		  BOOL bOver             是否重叠控制
返回值:   成功的发送数据长度
*/
//##ModelId=3BDCCE3D03DE
DWORD CAsyncCom::Write(BYTE *buff, DWORD bufflen,BOOL bOver)
{
	DWORD lenreturn;
	DWORD dwErrorFlags;
	COMSTAT ComStat;
	if(!IsOpen)
		return 0;
	PurgeComm(hComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
	BOOL fState = WriteFile(hComDev,buff,bufflen,&lenreturn,&write_os);
	if(!fState)
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			if(bOver)//bOver
			{
				while(!GetOverlappedResult(hComDev,&write_os,&lenreturn,TRUE)) 
				{ 
					if(GetLastError() == ERROR_IO_INCOMPLETE)
						continue; 
					else 
					{ 
						ClearCommError(hComDev,&dwErrorFlags,&ComStat);
						break; 
					} 
				}
			}
		}
		else
		{
			lenreturn = -1;
			ClearCommError(hComDev,&dwErrorFlags,&ComStat);
		}
	}
//	WriteFile_COMM(buff, bufflen,'s',TRUE);
	return lenreturn;
}

//##ModelId=3B2864BA011D
/*
功  能:数据接收函数,调用此函数接收数据到缓冲区中
设计者:
时  间:2001-5
函数名:Read(BYTE *pBuff, DWORD NumRead)
参  数:   BYTE *pBuff            接收数据缓冲区
          DWORD NumRead          请求接收数据长度
		  
返回值:   成功接收的数据长度
*/
//##ModelId=3BDCCE3D03DB
DWORD CAsyncCom::Read(BYTE *pBuff, DWORD NumRead)
{
	DWORD numByte;
 	COMSTAT  ComStat ;
 	DWORD dwErrorFlags;
//	DWORD len;
	BOOL fReadStat;
	if(!IsOpen)
		return 0;
	if(NumRead<=0)
		return 0;
	if(!ClearCommError(hComDev, &dwErrorFlags, &ComStat))
		return 0;
//	len = NumRead;
	fReadStat = ReadFile(hComDev,pBuff,NumRead,&numByte,&read_os);
	if (!fReadStat) 
	{
		if (GetLastError()==ERROR_IO_PENDING) 
		{ 
			while(!GetOverlappedResult(hComDev,&read_os,&numByte,TRUE)) 
			{ 
				if(GetLastError() == ERROR_IO_INCOMPLETE)
					continue; 
			} 
		} 
		else 
		{ 
			numByte=0; 
			ClearCommError(hComDev,&dwErrorFlags,&ComStat);
		} 
	}
//	WriteFile_COMM(pBuff, numByte,'r',TRUE);
	return numByte;

}

//##ModelId=3BDCCE3D03D1
CAsyncCom::ProcessEvent(DWORD Event,DWORD sign)
{
	switch(Event)
	{
	case EV_RXCHAR:
		ProcessReceiveData(sign);
		break;
//	case EV_TXEMPTY:
//		OnSend();
		break;
	case EV_ERR:
		OnError(sign);
		break;
	}
}

//##ModelId=3BDCCE3D03C7
void CAsyncCom::ProcessReceiveData(DWORD sign)
{
	OnReceive();
}

//##ModelId=3B2864BA00D6
/*
功  能:清除缓冲区的错误
设计者:
时  间:2001-5
函数名:ClearBuffError()
参  数:   无
返回值:   无
*/
//##ModelId=3BDCCE3D0395
CAsyncCom::ClearBuffError()
{
	DWORD len;
	COMSTAT comstat;
	PurgeComm(hComDev,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
	ClearCommError(hComDev,&len,&comstat);
}


void CAsyncCom::WriteFile_COMM(BYTE *buf, int Len,BYTE m_WR,BOOL Flags)
{
//	if(!Flags)
	return;
	CString str,temp,stemp;
	CString sfile,sDir;
	CFile file;
	BOOL bo;

	sfile.Format(".\\log\\COMM_CODE.txt");
	_mkdir(".\\log");
	bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite);
	if(!bo)
	{			
		bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite|CFile::modeCreate);
		if(!bo)
		{
			bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite|CFile::modeCreate);
			if(!bo)
			{
				return ;
			}
		}
	}

	str ="";
	for(int i = 0;i<Len;i++)
	{
		temp.Format("%02x ",buf[i]);
		str = str + temp;
	}		
	long len1 = file.GetLength();
	file.Seek(len1,CFile::begin);
	str.MakeUpper();
	stemp.Format("[ %s ] %s\r\n",m_WR=='s'?"Send   ":"Receive",str);
	file.Write(stemp.GetBuffer(stemp.GetLength()),stemp.GetLength());
	file.Close();
	return ;
}

⌨️ 快捷键说明

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