13.6.7 读取串口数据函数的实现
读串口函数:ReceiveChar()负责读取串口数据,实现如下:
- 01 void CMySerial::ReceiveChar(CMySerial* port, COMSTAT comstat)
- 02 {
- 03 BOOL bRead = TRUE;
- 04 BOOL bResult = TRUE;
- 05 DWORD dwError = 0;
- 06 DWORD BytesRead = 0;
- 07 unsigned char RXBuff;
- 08 //读取串口数据
- 09 for (;;)
- 10 {
- 11 EnterCriticalSection(&port->m_csCommunicationSync);
- 12 bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
- 13 LeaveCriticalSection(&port->m_csCommunicationSync);
- 14 if (comstat.cbInQue == 0)
- 15 { //无数据可读
- 16 break;
- 17 }
- 18 //锁定临界资源
- 19 EnterCriticalSection(&port->m_csCommunicationSync);
- 20 if (bRead)
- 21 {
- 22 bResult = ReadFile(port->m_hComm, //串口句柄
- 23 &RXBuff, //存放数据缓冲
- 24 1, //只读1个字节
- 25 &BytesRead, //实际读取数据数量
- 26 &port->m_ov); //Overlapped结构体
- 27 if (!bResult)
- 28 { //读取失败
- 29 switch (dwError = GetLastError())
- 30 { //错误代码
- 31 case ERROR_IO_PENDING:
- 32 { //数据尚未读完
- 33 bRead = FALSE;
- 34 break;
- 35 }
- 36 default:
- 37 { //一般错误处理方法
- 38 port->ProcessErrorMessage("ReadFile()");
- 39 break;
- 40 }
- 41 }
- 42 }
- 43 else
- 44 { //读取成功
- 45 bRead = TRUE;
- 46 }
- 47 }
- 48 if (!bRead)
- 49 { //读取失败处理
- 50 bRead = TRUE;
- 51 bResult = GetOverlappedResult(port->m_hComm, //串口句柄
- 52 &port->m_ov,//Overlapped 结构体53 &BytesRead, //读取的字节数
- 54 TRUE); //等待
- 55 if (!bResult)
- 56 { //错误处理
- 57 port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
- 58 }
- 59 }
- 60 LeaveCriticalSection(&port->m_csCommunicationSync); //释放临界资源
- 61 //向主窗体发送消息
- 62 ::SendMessage((port->m_pParent)->m_hWnd,
- 63 WM_COMM_RXCHAR, (WPARAM) RXBuff,
- 64 (LPARAM) port->m_nPortNr);
- 65 }
- 66 }
【代码解析】
第11~17行判断当前串口缓冲中是否已无数据可读,如是则直接退出循环。第22~26行在串口上读取1个字节的数据,第27行判断是否读取失败,如是,则在第29行判断错误原因,第31行判断是否读取动作尚未完成,如是则退出错误诊断,否则在第38行进行错误提示。如果尚未完成读取过程,则在第51~54行继续等待,直到完成。如果等待失败则在第57行进行错误提示。第62~64行向主窗体发送消息,通知主窗体串口接收到数据,并把刚刚读取的一个字节数据发送给主窗体。