下载地址如下:http://www.cppblog.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 ;
}
{
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平台使用过的最稳定实现,呵呵,经验总结,在多个地方使用过,请放心使用。
终于实现我说的写个串口编程专题的第一步,不容易,太忙了。