例子工程使用VS2003編譯通過。
下載地址如下:http://www.shnenglu.com/Files/dyj057/MySerialPort08-8-22.rar
所謂異步串口數據接收就是串口數據的接收是在一個獨立的線程完成了。當串口有數據返回時,會自動執行自定義的回調函數代碼,而不是像傳統的使用Read函數去串口數據。
我在PJ Naughter的串口類CSerialPort的基礎上,繼承得到了自己的CAsyncSerialPort類,還聲明了一個ISerialPortObserver接口來監視串口活動,如打開、關閉、數據發送完成,數據接收,處理錯誤信息等。實用的時候,從ISerialPortObserver繼承一個類,實現里面的純虛方法,然后把這個類的一個實例加入通過CAsyncSerialPort類中的void AtachObserver(ISerialPortObserver *pObserver)方法加入串口實例中,就能實現對串口活動的監控了。
其中最核心的代碼就是CAsyncSerialPort事件處理,實現數據的異步接收:
int CAsyncSerialPort::Run()
{
try
{
//events array
HANDLE waitHandles[4]= {
m_portClosingEvent,
m_readEvent,
m_breakEvent,
m_writeEvent};
WORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | \
EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
SetMask(dwStoredFlags);
DWORD dwMask;
SetBreakEvent(dwMask);
SetReadEvent(m_readOverlapped);
DWORD dwEventIndex;
while(TRUE)
{
dwEventIndex = ::WaitForMultipleObjects(4,waitHandles,false,INFINITE);
switch(dwEventIndex)
{
case WAIT_OBJECT_0:
TRACE(_T("Receive serial port close event, exit read thread.\n"));
return 0L;
case WAIT_OBJECT_0+1: //read event
{
HandleReadEvent(m_readOverlapped);
SetReadEvent(m_readOverlapped);
}
break;
case WAIT_OBJECT_0 +2: //break event
{
HandleBreakEvent(dwMask);
SetBreakEvent(dwMask);
}
break;
case WAIT_OBJECT_0 +3:
{
HandleWriteEvent(m_writeOverlapped);
}
break;
case WAIT_FAILED:
THROW_EX_CODE( ::GetLastError() );
default:
ASSERT(FALSE);
return 0L;
}
}
}
catch (CRuntimeException* e)
{
OnError(e->GetErrorMessage());
e->Delete();
}
return 0L;
}
該串口實現是我在Win32平臺使用過的最穩定實現,呵呵,經驗總結,在多個地方使用過,請放心使用。
終于實現我說的寫個串口編程專題的第一步,不容易,太忙了。
posted on 2007-08-22 19:59
天下無雙 閱讀(6342)
評論(5) 編輯 收藏 引用 所屬分類:
C/C++