例子工程使用VS2003編譯通過。
下載地址如下:http://m.shnenglu.com/Files/dyj057/MySerialPort08-8-22.rar
所謂異步串口數(shù)據(jù)接收就是串口數(shù)據(jù)的接收是在一個(gè)獨(dú)立的線程完成了。當(dāng)串口有數(shù)據(jù)返回時(shí),會(huì)自動(dòng)執(zhí)行自定義的回調(diào)函數(shù)代碼,而不是像傳統(tǒng)的使用Read函數(shù)去串口數(shù)據(jù)。
我在PJ Naughter的串口類CSerialPort的基礎(chǔ)上,繼承得到了自己的CAsyncSerialPort類,還聲明了一個(gè)ISerialPortObserver接口來監(jiān)視串口活動(dòng),如打開、關(guān)閉、數(shù)據(jù)發(fā)送完成,數(shù)據(jù)接收,處理錯(cuò)誤信息等。實(shí)用的時(shí)候,從ISerialPortObserver繼承一個(gè)類,實(shí)現(xiàn)里面的純虛方法,然后把這個(gè)類的一個(gè)實(shí)例加入通過CAsyncSerialPort類中的void AtachObserver(ISerialPortObserver *pObserver)方法加入串口實(shí)例中,就能實(shí)現(xiàn)對(duì)串口活動(dòng)的監(jiān)控了。
其中最核心的代碼就是CAsyncSerialPort事件處理,實(shí)現(xiàn)數(shù)據(jù)的異步接收:
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;
}
該串口實(shí)現(xiàn)是我在Win32平臺(tái)使用過的最穩(wěn)定實(shí)現(xiàn),呵呵,經(jīng)驗(yàn)總結(jié),在多個(gè)地方使用過,請(qǐng)放心使用。
終于實(shí)現(xiàn)我說的寫個(gè)串口編程專題的第一步,不容易,太忙了。
posted on 2007-08-22 19:59
天下無雙 閱讀(6352)
評(píng)論(5) 編輯 收藏 引用 所屬分類:
C/C++