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

📄 serialcomm.cpp

📁 云台控制的工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if( pPort == NULL )
		return FALSE;

	BOOL successed = pPort->GetOverlappedResult( m_BreakOverlapped, dwReadBytes, FALSE );
	if( successed )
	{
		m_pPortComm->OnComBreak(dwMask);	// 调用处理过程
		return TRUE;
	}

	return FALSE;
}


//---------------------------------------------------------------------------------------
//	根据读写模式,执行线程
//---------------------------------------------------------------------------------------

void CSerialReadThread::Execute()
{
	switch( m_pPortComm->GetReceiveMode() )
	{
	case ManualReceiveByQuery:
		ExecuteByManualQueryRecvMode();
		break;
	case ManualReceiveByConst:
		ExecuteByManualConstRecvMode();
		break;
	case AutoReceiveBySignal:
		ExecuteByAutoSignalRecvMode();
		break;
	default:
		// 中断模式
		ExecuteByAutoBreakRecvMode();
	}
}

//---------------------------------------------------------------------------------------
//	常用方式1:串口收到数据后自动通知主线程
//---------------------------------------------------------------------------------------

void CSerialReadThread::ExecuteByAutoSignalRecvMode()
{
	DWORD  dwMask = 0;
	HANDLE WaitHandles[3];	// 监听事件数组
	DWORD  dwSignaledHandle;

	//	第一个信号量为线程结束运行的通知
	//	第二个信号量读取重叠操作,串口收到数据后的通知
	//	第三个信号量中断重叠操作
	WaitHandles[0] = m_pPortComm->GetCloseHandle();
	WaitHandles[1] = m_ReadOverlapped.hEvent;
	WaitHandles[2] = m_BreakOverlapped.hEvent;

	CSerialPort* pPort = m_pPortComm->GetSerialPort();
	if( pPort == NULL )
		goto EndThread;
	pPort->SetMask( EV_ERR | EV_RLSD | EV_RING );

	if( !SetBreakEvent(dwMask) )
		goto EndThread;
	//	设置读事件
	if( !SetReadEvent(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( !HandleReadEvent(m_ReadOverlapped) )
				goto EndThread;
			if( !SetReadEvent(m_ReadOverlapped) )
				goto EndThread;
			break;

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

		default:
			// goto EndThread;
			break;
		}
	}

EndThread:
	pPort->Purge( PURGE_RXABORT | PURGE_RXCLEAR );
	::CloseHandle( m_ReadOverlapped.hEvent );
	::CloseHandle( m_BreakOverlapped.hEvent );
}

//---------------------------------------------------------------------------------------
//	常用方式2:主线程在需要数据时主动查询串口是否已收到数据
//---------------------------------------------------------------------------------------

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

	//	第一个信号量为线程结束运行的通知
	//	第二个信号量无
	//	第三个信号量无
	WaitHandles[0] = m_pPortComm->GetCloseHandle();
	CSerialPort* pPort = m_pPortComm->GetSerialPort();
	if( pPort == NULL )
		goto EndThread;

	pPort->SetMask( EV_ERR | EV_RLSD | EV_RING ); 
	pPort->SetBreak();
	for(;;)
	{
		dwSignaledHandle = ::WaitForMultipleObjects(1, WaitHandles, FALSE, INFINITE);
		switch( dwSignaledHandle )
		{
		case WAIT_OBJECT_0:
			goto EndThread; 
			break;

		default:
			// goto EndThread;
			break;
		}

		pPort->GetMask(dwMask);
		if( dwMask > 0 )
			m_pPortComm->OnComBreak(dwMask);
	}

EndThread:
	pPort->Purge(PURGE_RXABORT | PURGE_RXCLEAR);
}

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

	//	第一个信号量为线程结束运行的通知
	//	第二个信号量中断重叠操作
	//	第三个信号量无
	WaitHandles[0] = m_pPortComm->GetCloseHandle();
	WaitHandles[1] = m_BreakOverlapped.hEvent;
	CSerialPort* pPort = m_pPortComm->GetSerialPort();
	if( pPort == NULL )
		goto EndThread;

	pPort->SetMask( EV_ERR | EV_RLSD | EV_RING );
	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( !HandleBreakEvent(dwMask) )
				goto EndThread;
			if( !SetBreakEvent(dwMask) )
				goto EndThread;
			break;

		default:
			// goto EndThread;
			break;
		}
	}

EndThread:
	pPort->Purge( PURGE_RXABORT | PURGE_RXCLEAR );
	::CloseHandle( m_ReadOverlapped.hEvent );
	::CloseHandle( m_BreakOverlapped.hEvent );
}

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

	//	第一个信号量为线程结束运行的通知
	//	第二个信号量中断重叠操作
	//	第三个信号量无
	WaitHandles[0] = m_pPortComm->GetCloseHandle();
	WaitHandles[1] = m_BreakOverlapped.hEvent;
	CSerialPort* pPort = m_pPortComm->GetSerialPort();
	if( pPort == NULL )
		goto EndThread;

	pPort->SetMask(EV_ERR | EV_RLSD | EV_RING | EV_RXCHAR);
	if( !SetBreakEvent(dwMask) )
		goto EndThread;
	//	设置读事件
	if( !SetReadEvent(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( !HandleReadEvent(m_BreakOverlapped) )
					goto EndThread;
				if( !SetReadEvent(m_BreakOverlapped) )
					goto EndThread;
			}
			else
			{
				if( !HandleBreakEvent(dwMask) )
					goto EndThread;
				if( !SetBreakEvent(dwMask) )
					goto EndThread;
			}
			break;

		default:
			// goto EndThread;
			break;
		}
	}

EndThread:
	pPort->Purge(PURGE_RXABORT | PURGE_RXCLEAR);
	::CloseHandle( m_ReadOverlapped.hEvent );
	::CloseHandle( m_BreakOverlapped.hEvent );  
}

static DWORD WINAPI ThreadFunc(LPVOID lpParam)
{ 
    CSerialReadThread* pThread = (CSerialReadThread*)lpParam;
	ASSERT(pThread);

	pThread->m_IsTerminated = FALSE;
    pThread->Execute();
	pThread->m_IsTerminated = TRUE;

	return 0;
} 

void CSerialReadThread::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 );
	::SetThreadPriority( m_hThread, THREAD_PRIORITY_NORMAL );
}

void CSerialReadThread::Terminate()
{
	if (m_hThread == NULL) 
	{
		TRACE( _T("CreateThread failed.") );
	}
	else 
	{
		if( !IsTerminated() )
		{
			if( WaitForSingleObject(m_hThread, 1000) != WAIT_OBJECT_0 )
			{	//	先等 1 秒,仍没有结束,强制结束
				::TerminateThread( m_hThread, 0 );
			}
		}
		CloseHandle( m_hThread );
	}
}

void CSerialReadThread::Resume()
{
	ResumeThread( m_hThread );
}

void CSerialReadThread::BandSerialPort(CSerialComm* pPort)
{
	ASSERT(pPort);
	m_pPortComm = pPort;

	//	创建异步读取事件
	if( m_pPortComm->IsOverlapped() )
	{
		m_ReadOverlapped.hEvent  = ::CreateEvent(NULL, FALSE, FALSE, NULL);	
		ASSERT( m_ReadOverlapped.hEvent );  
		m_BreakOverlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE,NULL);
		ASSERT( m_BreakOverlapped.hEvent ); 
	}
}

DWORD CSerialReadThread::ReadInput(void* pBuf, DWORD Count, DWORD dwMilliseconds)
{
	DWORD dwRead = 0;
	CSerialPort* pPort = m_pPortComm->GetSerialPort();
	if( pPort == NULL )
		return 0;

	//	正在等待
	if( !pPort->Read(pBuf, Count, m_ReadOverlapped, &dwRead) )
	{
		//	等待,直到有数据或超时
		if( WaitForSingleObject(m_ReadOverlapped.hEvent, dwMilliseconds) == WAIT_OBJECT_0 )
			pPort->GetOverlappedResult( m_ReadOverlapped, dwRead, FALSE );
	}

	return dwRead;
}

⌨️ 快捷键说明

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