串口程序中函数使用WaitCommEvent、ClearCommError、GetcommMask
2017-06-06 12:11
204 查看
在串口程序中的几个函数的联合使用
一、首先是利用WaitCommEvent
来等待串口事件的被触发,这些事件是指在该函数被调用前,我们自己设置好的能触发串口线程的有效事件。
主要包括3类事件:
1.
函数SetCommMask (ceSeries->m_hComm, EV_RXCHAR |EV_CTS | EV_DSR )设置的数据接收中断
2.用户中断线程的操作。
3.
用户发送数据所产生的中断。
该函数相当于利用事件来同步,实际函数也是这么设计的。但没有有效中断触发,线程会一直在这里等待。
一旦被触发,程序才能继续往下执行。
二、函数WaitCommEvent执行完成后,他的返回值若为零,说明有错误,这时候用GetLastError来查询错误类型。
三、函数WaitCommEvent执行返回值若为1,则用ClearCommError来清除错误,并查询串口的状态,得到comstat的值。
四、检查ClearCommError所查询的串口状态comstat.cbInQue的值,若不大于0,说明错误。继续等待事件的触发
五、若omstat.cbInQue大于0,说明buffer里面有字符。在使用WaitForMultipleObjects函数确认事件,并执行对应的操作。
//WaitCommEvent函数为指定的通信资源监听一系列的Event,这些Event可以由
SetcommMask和 GetcommMask函数来设置和查询。
例子:
bResult =WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
if (!bResult)
{
// If WaitCommEvent() returns FALSE,process
the last error to determin
switch (dwError =GetLastError())
{
case ERROR_IO_PENDING:
{
break;
}
case 87:
{
break;
}
default:
{
port->ProcessErrorMessage("WaitCommEvent()");
break;
}
}
}
else
{
bResult =ClearCommError(port->m_hComm,
&dwError, &comstat);
if (comstat.cbInQue == 0)
continue;
} // end if bResult
//m_hEventArray[0] =m_hShutdownEvent; //
highest priority
//m_hEventArray[1] = m_ov.hEvent;
//m_hEventArray[2] = m_hWriteEvent;
Event = WaitForMultipleObjects(3,port->m_hEventArray, FALSE, INFINITE);
switch (Event)
{
case 0:
{
//
Shutdown event. This is event zero so it will be// thehigest priority and be serviced first.
CloseHandle(port->m_hComm);
port->m_hComm=NULL;
port->m_bThreadAlive
=FALSE;
//
Kill this thread. break is not needed, but makes me feelbetter.
AfxEndThread(100);
break;
}
case 1: // read event
{
GetCommMask(port->m_hComm,&CommEvent);
if
(CommEvent & EV_RXCHAR)
//
Receive character event from port.
ReceiveChar(port,
comstat);
if
(CommEvent & EV_CTS)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_CTS_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_BREAK)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_BREAK_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_ERR)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_ERR_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_RING)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RING_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_RXFLAG)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RXFLAG_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
break;
}
case 2: // write event
{
//
Write character event from port
WriteChar(port);
break;
}
} // end switch
} // closeforever loop
一、首先是利用WaitCommEvent
来等待串口事件的被触发,这些事件是指在该函数被调用前,我们自己设置好的能触发串口线程的有效事件。
主要包括3类事件:
1.
函数SetCommMask (ceSeries->m_hComm, EV_RXCHAR |EV_CTS | EV_DSR )设置的数据接收中断
2.用户中断线程的操作。
3.
用户发送数据所产生的中断。
该函数相当于利用事件来同步,实际函数也是这么设计的。但没有有效中断触发,线程会一直在这里等待。
一旦被触发,程序才能继续往下执行。
二、函数WaitCommEvent执行完成后,他的返回值若为零,说明有错误,这时候用GetLastError来查询错误类型。
三、函数WaitCommEvent执行返回值若为1,则用ClearCommError来清除错误,并查询串口的状态,得到comstat的值。
四、检查ClearCommError所查询的串口状态comstat.cbInQue的值,若不大于0,说明错误。继续等待事件的触发
五、若omstat.cbInQue大于0,说明buffer里面有字符。在使用WaitForMultipleObjects函数确认事件,并执行对应的操作。
//WaitCommEvent函数为指定的通信资源监听一系列的Event,这些Event可以由
SetcommMask和 GetcommMask函数来设置和查询。
例子:
bResult =WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
if (!bResult)
{
// If WaitCommEvent() returns FALSE,process
the last error to determin
switch (dwError =GetLastError())
{
case ERROR_IO_PENDING:
{
break;
}
case 87:
{
break;
}
default:
{
port->ProcessErrorMessage("WaitCommEvent()");
break;
}
}
}
else
{
bResult =ClearCommError(port->m_hComm,
&dwError, &comstat);
if (comstat.cbInQue == 0)
continue;
} // end if bResult
//m_hEventArray[0] =m_hShutdownEvent; //
highest priority
//m_hEventArray[1] = m_ov.hEvent;
//m_hEventArray[2] = m_hWriteEvent;
Event = WaitForMultipleObjects(3,port->m_hEventArray, FALSE, INFINITE);
switch (Event)
{
case 0:
{
//
Shutdown event. This is event zero so it will be// thehigest priority and be serviced first.
CloseHandle(port->m_hComm);
port->m_hComm=NULL;
port->m_bThreadAlive
=FALSE;
//
Kill this thread. break is not needed, but makes me feelbetter.
AfxEndThread(100);
break;
}
case 1: // read event
{
GetCommMask(port->m_hComm,&CommEvent);
if
(CommEvent & EV_RXCHAR)
//
Receive character event from port.
ReceiveChar(port,
comstat);
if
(CommEvent & EV_CTS)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_CTS_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_BREAK)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_BREAK_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_ERR)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_ERR_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_RING)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RING_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
if
(CommEvent & EV_RXFLAG)
::SendMessage(port->m_pOwner->m_hWnd,WM_COMM_RXFLAG_DETECTED,
(WPARAM) 0, (LPARAM) port->m_nPortNr);
break;
}
case 2: // write event
{
//
Write character event from port
WriteChar(port);
break;
}
} // end switch
} // closeforever loop
相关文章推荐
- 怎样在TI stellaris lm3sxxx 程序中使用C语言printf()函数进行串口输出
- 串口 WaitCommEvent 、GetLastError、ClearCommError、WaitForMultipleObjects的联合使用
- Eclipse编译Arduino程序不能使用串口函数Serial.begin解决办法
- linux 系统下使用C程序实现时钟的函数
- 使用SerialPort类设计串口通讯程序
- 在C#程序中直接使用VB.NET中丰富的函数
- 使用SerialPort类设计串口通讯程序
- 一个使用Java读取串口的程序
- 这是我在写程序中经常使用的一些函数,但有时会忘.将积累以下……
- 使用SerialPort类设计串口通讯程序 (VS2005)[转载]
- 使用CreateProcess函数运行其他程序
- 使用SerialPort 类设计串口通讯程序
- 如何使用Java读取串口的程序
- 使用SerialPort类设计串口通讯程序
- 使用SerialPort类设计串口通讯程序 (VS2005)
- 使用Win32创建串口通讯程序
- 显示程序使用最大内存函数
- 调试使用了函数模块的程序时需要注意的一个小问题
- 串口调试精灵的使用和串口程序调试技巧
- [VB.NET]为何一使用串口类SerialPort中的HandShake程序就会没响应?