標籤:串口通訊
在Win32下,可以使用兩種編程方式實現串口通訊,其一是使用ActiveX控制項(ActiveX是Microsoft對於一系列策略性物件導向程式技術和工具的稱呼,其中主要的技術是元件物件模型(COM)),這種方法程式簡單,但欠靈活。其二是調用Windows的API函數,這種方法可以清楚地掌握串口通訊的機制,並且自由靈活。
本文我們只介紹API串口通訊部分。
串口的操作可以有兩種操作方式:同步操作方式和重疊操作方式(又稱為非同步作業方式)。同步操作時,API函數會阻塞直到操作完成以後才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而重疊操作方式,API函數會立即返回,操作在後台進行,避免線程的阻塞。
無論那種操作方式,一般都通過四個步驟來完成:
(1) 開啟串口
(2) 配置串口
(3) 讀寫串口
(4) 關閉串口
1、開啟串口
Win32系統把檔案的概念進行了擴充。無論是檔案、通訊裝置、具名管道、郵件槽、磁碟、還是控制台,都是用API函數CreateFile來開啟或建立的。
2、配置串口
在開啟通訊裝置控制代碼後,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如傳輸速率、資料位元數、同位和停止位元等資訊。在查詢或配置串口的屬性時,都要用DCB結構來作為緩衝區。
一般用CreateFile開啟串口後,可以調用GetCommState函數來擷取串口的初始配置。要修改串口的配置,應該先修改DCB結構,然後再調用SetCommState函數設定串口。
除了在BCD中的設定外,程式一般還需要設定I/O緩衝區的大小和逾時。Windows用I/O緩衝區來暫存串口輸入和輸出的資料。如果通訊的速率較高,則應該設定較大的緩衝區。調用SetupComm函數可以設定串列口的輸入和輸出緩衝區的大小。
在用ReadFile和WriteFile讀寫串列口時,需要考慮逾時問題。逾時的作用是在指定的時間內沒有讀入或發送指定數量的字元,ReadFile或WriteFile的操作仍然會結束。
要查詢當前的逾時設定應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設定逾時。
讀寫串口的逾時有兩種:間隔逾時和總逾時。間隔逾時是指在接收時兩個字元之間的最大時延。總逾時是指讀寫操作總共花費的最大時間。寫操作只支援總逾時,而讀操作兩種逾時均支援。用COMMTIMEOUTS結構可以規定讀寫操作的逾時。
在讀寫串口之前,還要用PurgeComm函數清空緩衝區。
3、讀寫串口
我們使用ReadFile和WriteFile讀寫串口.
在用ReadFile和WriteFile讀寫串口時,既可以同步執行,也可以重疊執行。在同步執行時,函數直到操作完成後才返回。這意味著同步執行時線程會被阻塞,從而導致效率下降。在重疊執行時,即使操作還未完成,這兩個函數也會立即返回,費時的I/O操作在後台進行。
ReadFile和WriteFile函數是同步還是非同步由CreateFile函數決定,如果在調用CreateFile建立控制代碼時指定了FILE_FLAG_OVERLAPPED標誌,那麼調用ReadFile和WriteFile對該控制代碼進行的操作就應該是重疊的;如果未指定重疊標誌,則讀寫操作應該是同步的。ReadFile和WriteFile函數的同步或者非同步應該和CreateFile函數相一致。
ReadFile函數只要在串口輸入緩衝區中讀入指定數量的字元,就算完成操作。而WriteFile函數不但要把指定數量的字元拷入到輸出緩衝區,而且要等這些字元從串列口送出去後才算完成操作。
如果操作成功,這兩個函數都返回TRUE。需要注意的是,當ReadFile和WriteFile返回FALSE時,不一定就是操作失敗,線程應該調用GetLastError函數分析返回的結果。例如,在重疊操作時如果操作還未完成函數就返回,那麼函數就返回FALSE,而且GetLastError函數返回ERROR_IO_PENDING。這說明重疊操作還未完成。
重疊I/O非常靈活,它也可以實現阻塞(例如我們可以設定一定要讀取到一個資料才能進行到下一步操作)。有兩種方法可以等待操作完成:一種方法是用象WaitForSingleObject這樣的等待函數來等待OVERLAPPED結構的hEvent成員;另一種方法是調用GetOverlappedResult函數等待,後面將示範說明。
4、關閉串口
利用API函數關閉串口非常簡單,只需使用CreateFile函數返回的控制代碼作為參數調用CloseHandle即可。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
VC++串口通訊基礎知識