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

📄 comport.cpp

📁 多线程串口通信程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   {
      if(!this->HandleBreakEvent(dwMask))
		  return false;
	  goto SetBegin;
   }

    DWORD error=::GetLastError();
	if(error==ERROR_IO_PENDING)
	{ return true; }
	else
	{ return false; }
}

bool CReadComThread::HandleBreakEvent(DWORD dwMask)
{
   DWORD dwReadBytes;
   bool successed=
      this->m_pPort->GetSerialPort()->GetOverlappedResult(this->m_BreakOverlapped,dwReadBytes,false);
   if(successed)
   {
	   this->m_pPort->ComBreak(dwMask); //调用处理过程
	   return true;
   }
   return false;
}

void CReadComThread::Execute()
{

	if(this->m_pPort->GetReceiveMode()==CComPort::ManualReceiveByQuery)
	{
	   this->ExecuteByManualQueryRecvMode(); 
	}
	else if(this->m_pPort->GetReceiveMode()==CComPort::ManualReceiveByConst)
	{
       this->ExecuteByManualConstRecvMode(); 	
	}
	else if(this->m_pPort->GetReceiveMode()==CComPort::AutoReceiveBySignal)
	{
	   this->ExecuteByAutoSignalRecvMode(); 
	}
	else//中断模式
	{
       this->ExecuteByAutoBreakRecvMode(); 
	}

}
void CReadComThread::ExecuteByAutoSignalRecvMode()
{
	DWORD dwMask=0;
	HANDLE WaitHandles[3]; //监听事件数组
	DWORD dwSignaledHandle;
	//DWORD dwStoredFlags = EV_ERR | EV_RLSD | EV_RING;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;

	WaitHandles[0] = this->m_pPort->GetCloseHandle();
	WaitHandles[1] = this->m_ReadOverlapped.hEvent;
	WaitHandles[2] = this->m_BreakOverlapped.hEvent;

	this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags); 
	if(!SetBreakEvent(dwMask))
		goto EndThread;
	//设置读事件
	if(!SetReadEvent(this->m_ReadOverlapped))
		goto EndThread;

    //设置comEvent
	for(;;)
	{
	   dwSignaledHandle=::WaitForMultipleObjects(3,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
	   {
	      case WAIT_OBJECT_0:
              goto EndThread; 
			  break;

	      case WAIT_OBJECT_0+1:
              if(!this->HandleReadEvent(this->m_ReadOverlapped))
			    goto EndThread;
   			  if(!this->SetReadEvent(this->m_ReadOverlapped))
        		  goto EndThread;
			  break;

	      case WAIT_OBJECT_0+2:
              if(!this->HandleBreakEvent(dwMask))
    				goto EndThread;
 
			  if(!this->SetBreakEvent(dwMask))
	        		  goto EndThread;
			  break;

		  default:
			  //goto EndThread;
			  break;
	   }
	   
  
	}

    EndThread:
	  	this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR);  
	    ::CloseHandle(this->m_ReadOverlapped.hEvent);
	    ::CloseHandle(this->m_BreakOverlapped.hEvent);  
        return ;   

}

void CReadComThread::ExecuteByManualQueryRecvMode()
{
	DWORD dwMask=0;
	HANDLE WaitHandles[2]; //监听事件数组
	DWORD dwSignaledHandle;

	WaitHandles[0] = this->m_pPort->GetCloseHandle();

 	/*this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags); 
    this->m_pPort->GetSerialPort()->SetBreak(); */
 	for(;;)
	{
	   dwSignaledHandle=::WaitForMultipleObjects(1,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
	   {
	      case WAIT_OBJECT_0:
              goto EndThread; 
			  break;

		  default:
			  //goto EndThread;
			  break;
	   }
 	   this->m_pPort->GetSerialPort()->GetMask(dwMask);
	   if(dwMask>0)
	   {
		     this->m_pPort->ComBreak(dwMask); 	     
	   }
	}

    EndThread:
	  	this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR);  
        return ;   

}

void CReadComThread::ExecuteByManualConstRecvMode()
{
	DWORD dwMask=0;
	HANDLE WaitHandles[2]; //监听事件数组
	DWORD dwSignaledHandle;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;

	WaitHandles[0] = this->m_pPort->GetCloseHandle();
	WaitHandles[1] = this->m_BreakOverlapped.hEvent;

	this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags); 

	if(!SetBreakEvent(dwMask))
		goto EndThread;
		
    //设置comEvent
	for(;;)
	{
	   dwSignaledHandle=::WaitForMultipleObjects(2,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
	   {
	      case WAIT_OBJECT_0:
              goto EndThread; 
			  break;

	      case WAIT_OBJECT_0+1:
			  if(!this->HandleBreakEvent(dwMask))
			    goto EndThread;
    		  if(!this->SetBreakEvent(dwMask))
	        	goto EndThread;
			  break;

		  default:
			  //goto EndThread;
			  break;
	   }
	   
  
	}

    EndThread:
	  	this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR);  
	    ::CloseHandle(this->m_ReadOverlapped.hEvent);
	    ::CloseHandle(this->m_BreakOverlapped.hEvent);  
        return ;   

}
void CReadComThread::ExecuteByAutoBreakRecvMode()
{
   	DWORD dwMask=0;
	HANDLE WaitHandles[2]; //监听事件数组
	DWORD dwSignaledHandle;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG ;//??| EV_TXEMPTY 添加后在首次执行时总是接收不到全部数据

	WaitHandles[0] = this->m_pPort->GetCloseHandle();
	WaitHandles[1] = this->m_BreakOverlapped.hEvent;

	
	this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags); 

    //this->m_BreakOverlapped??两个事件同时给一个重叠结果的话??
	if(!SetBreakEvent(dwMask))
		goto EndThread;
	//设置读事件
	if(!SetReadEvent(this->m_BreakOverlapped))
		goto EndThread;

    //设置comEvent
	for(;;)
	{
	   dwSignaledHandle=::WaitForMultipleObjects(2,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
	   {
	      case WAIT_OBJECT_0:
              goto EndThread; 
			  break;

	      case WAIT_OBJECT_0+1:
              if((dwMask&EV_RXCHAR)==EV_RXCHAR)
			  {
                  if(!this->HandleReadEvent(this->m_BreakOverlapped))
					 goto EndThread;
                  if(!SetReadEvent(this->m_BreakOverlapped))
		             goto EndThread;
			  }
			  else
			  {
			      if(!this->HandleBreakEvent(dwMask))
			        	goto EndThread;
    			  if(!this->SetBreakEvent(dwMask))
	        		    goto EndThread;
			  }
			  break;

		  default:
			  //goto EndThread;
			  break;
	   }
	   
  
	}

    EndThread:
	  	this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR);  
	    ::CloseHandle(this->m_ReadOverlapped.hEvent);
	    ::CloseHandle(this->m_BreakOverlapped.hEvent);  
        return ;   

}

DWORD WINAPI ThreadFunc(LPVOID  lpParam ) 
{ 
    CReadComThread* pThread =(CReadComThread*)lpParam;
	ASSERT(pThread);
	pThread->m_IsTerminated = false;
    pThread->Execute(); 
	pThread->m_IsTerminated = true;
	return 0;
} 

void CReadComThread::Create()
{
    m_hThread = CreateThread( 
        NULL,                        // no security attributes 
        0,                           // use default stack size  
        ThreadFunc,                  // thread function 
        this,                // argument to thread function 
        CREATE_SUSPENDED,           // use default creation flags 
        &dwThreadId);                // returns the thread identifier 
	::SetThreadPriority(m_hThread,THREAD_PRIORITY_HIGHEST); 
    
}

void CReadComThread::Terminate()
{
   char szMsg[80];
   if (m_hThread == NULL) 
   {
      wsprintf( szMsg, "CreateThread failed." ); 
	  ::MessageBox(NULL,szMsg,"ok",0);
   }
   else 
   {
      if(!this->IsTerminated())
	  {
	     Sleep(1000);
	  }
	  if(!this->IsTerminated())
	  {
         Sleep(1000);
         //::TerminateThread(m_hThread,0);
	  }
      CloseHandle( m_hThread );
   }
}

void CReadComThread::Resume()
{
   ResumeThread(this->m_hThread); 
}

void CReadComThread::BandSerialPort(CComPort* pPort)
{
	ASSERT(pPort);
	this->m_pPort = pPort;
	//创建异步读取事件
     
	if(this->m_pPort->IsOverlapped())
	{
	   this->m_ReadOverlapped.hEvent =::CreateEvent(NULL,true,false,NULL);	
	   ASSERT(this->m_ReadOverlapped.hEvent);  
       this->m_BreakOverlapped.hEvent = ::CreateEvent(NULL,true,false,NULL);
	   ASSERT(this->m_BreakOverlapped.hEvent); 
	}
	
}

DWORD CReadComThread::ReadInput(void* pBuf,DWORD Count,DWORD dwMilliseconds)
{
	DWORD dwRead=0;
	if(!this->m_pPort->GetSerialPort()->Read(pBuf,Count,this->m_ReadOverlapped,&dwRead))
	{
		if(WaitForSingleObject(this->m_ReadOverlapped.hEvent,dwMilliseconds)==WAIT_OBJECT_0)
		{
		    this->m_pPort->GetSerialPort()->GetOverlappedResult(this->m_ReadOverlapped,dwRead,false);
		}
	}

	return dwRead;   
   
}

}

⌨️ 快捷键说明

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