串口通訊WaitCommEvent 、GetLastError、ClearCommError、...


一、首先是利用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM