一、首先是利用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// the higest 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 feel better. 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 } // close forever loop