Windows串列埠程式設計

2021-04-20 04:39:37 字數 3256 閱讀 5465

一、基本知識

win32下串列埠通訊與16位串列埠通訊有很大的區別。在win32下,可以使用兩種程式設計方式實現串列埠通訊,其一是呼叫的windows的api函式,其二是使用activex控制項。使用api 呼叫,可以清楚地掌握串列埠通訊的機制,熟悉各種配置和自由靈活採用不同的流控進行串列埠通訊。下面介紹串列埠操作的基本知識。

1.dcb配置

dcb(device control block)結構定義了串列埠通訊裝置的控制設定。許多重要設定都是在dcb結構中設定的,有三種方式可以初始化dcb。

(1)通過getcommstate()函式得dcb的初始值,其使用方式為:

dcb dcb = ;

if (!getcommstate(hcomm, &dcb))

// error getting current dcb settings

else

// dcb is ready for use.

(2)用buildcommdcb()函式初始化dcb結構,該函式填充 dcb的波特率、奇偶校驗型別、資料位、停止位。對於流控成員函式設定了預設值。其用法是:

dcb dcb;

fillmemory(&dcb, sizeof(dcb), 0);

dcb.dcblength = sizeof(dcb);

if (!buildcommdcb(「9600,n,8,1", &dcb))

else

// dcb is ready for use.

(3)用setcommstate()函式手動設定dcb初值。用法如下:

dcb dcb;

fillmemory(&dcb, sizeof(dcb), 0);

if (!getcommstate(hcomm, &dcb)) // get current dcb

// error in getcommstate

return false;

// update dcb rate.

dcb.baudrate = cbr_9600 ;

// set new state.

if (!setcommstate(hcomm, &dcb))

// error in setcommstate.

possibly a problem with the communications

// port handle or a problem with the dcb structure itself.

手動設定dcb值時,dcb的結構的各成員的含義,可以參看msdn幫助。

2.流控設定

硬體流控:串列埠通訊中的硬體流控有兩種,dte/dsr方式和rts/cts方式,這與dcb結構的初始化有關係,dcb結構中的 outxctsflow、 foutxdsrflow、fdsrsensitivity、frtscontrol、fdtrcontrol幾個成員的初始值很關鍵,不同的值代表不同流控,也可以自己設定流控,但建議採用標準流行的流控方式。採用硬體流控時,dte、dsr、rts、cts的邏輯位直接影響到資料的讀寫及收發資料的緩衝區控制。

軟體流控:串列埠通訊中採用特殊字元xon和xoff作為控制串列埠資料的收發。與此相關的dcb成員是:fout、finx、xoffchar、xonchar、 xofflim和xonlim。具體含義參見msdn幫助。

讀操作:readfile()函式用於完成讀操作。非同步方式的讀操作為:

寫操作:與讀操作相似,故不詳述,呼叫的api函式是: writefile函式。

串列埠狀態:

(1)通訊事件:用setcommmask()函式設定想要得到的通訊事件的掩碼,再呼叫waitcommevent()函式檢測通訊事件的發生。可設定的通訊事件標誌(即setcommmask()函式所設定的掩碼)可以有ev_break、ev_cts、ev_dsr、 ev_err、ev_ring、ev_rlsd、ev_rxchar、ev_rxflag、ev_txempty。

注意:1對於ev_ring標誌的設定,win95是不會返回ev_ring事件的,因為win95不檢測該事件。2設定ev_rxchar,可以檢測到字元到達,但是在繫結此事件和readfile()函式一起讀取串列埠接收資料時,可能會出現錯誤,造成少讀位元組數,具體原因檢視msdn幫助。可以採用迴圈讀的辦法,另外乙個比較好的解決辦法是呼叫clearcommerror()函式,確定在一次讀操作中在緩衝區中等待被讀的位元組數。

(2)錯誤處理和通訊狀態:在串列埠通訊中,可能會產生很多的錯誤,使用clearcommerror()函式可以檢測錯誤並且清除錯誤條件。

(3)modem狀態:用setcommmask()可以包含很多事件標誌,但是這些事件標誌只指示在串列埠線路上的電壓變化情況。而呼叫 getcommmodemstatus()函式可以獲得線路上真正的電壓狀態。

擴充套件函式:如果應用程式想用自己的流控,可以使用 escapecommfunction()函式設定dtr和rts線路的電平。

關閉串列埠:程式結束或需要釋放串列埠資源時,應該正確關閉串列埠,關閉串列埠比較簡單,使用api呼叫closehandle()關閉串列埠的控制代碼就可以了。

呼叫方法為:closehandle(hcomm);

二、實現

1.程式設計思路

對於不同的應用程式,雖然介面不同,但是如果採用串列埠與主機之間的通訊,對串列埠的處理方式大致相似,無非就是通過串列埠收發資料,對於通過串列埠接收到的資料,交給上層軟體處理顯示,對於上層要發給串列埠的資料,進行**。但在實際程式設計中,由於採用的通訊方式和流控不同,串列埠設定也不同,這就涉及到 dcb的初始化問題和讀寫串列埠等細節問題。串列埠通訊應用程式設計的總體思路(即操作過程)是:首先,確定要開啟的串列埠名、波特率、奇偶校驗方式、資料位、停止位,傳遞給createfile()函式開啟特定串列埠;其次,為了保護系統對串列埠的初始設定,呼叫 getcommtimeouts()得到串列埠的原始超時設定;然後,初始化dcb物件,呼叫setcommstate() 設定dcb,呼叫setcommtimeouts()設定串列埠超時控制;再次,呼叫setupcomm()設定串列埠接收傳送資料的緩衝區大小,串列埠的設定就基本完成,之後就可以啟動讀寫執行緒了。

2.實現細節

在半雙工的情況下,首先完成必要的串列埠配置,成功開啟串列埠、dcb設定、超時設定;然後開啟執行緒,如: cwinthread hserialthread = (cwinthread*) afxbeginthread(serialoperation,hwnd,thread_priority_normal); 其中開啟之執行緒為serialoperation,優先順序為普通。

全雙工情況下的串列埠程式設計,與單工差不多,區別僅僅在於啟動雙線程,分別為讀執行緒和寫執行緒,讀執行緒根據不同的事件或訊息,通過不斷查詢串列埠所收到的有效資料,完成讀操作;寫執行緒通過接收主線程的傳送資料事件和要傳送的資料,向串列埠傳送。

Windows 串列埠程式設計

造冰箱的大熊貓 cnblogs 2019 1 27 將windows下串列埠程式設計相關資訊進行下簡單小結,以備後用。1 開啟串列埠 開啟串列埠使用createfile 函式。以開啟com6為例 handle hcomm hcomm createfile text com6 generic read...

Windows 下串列埠程式設計

經常需要用到windows下的串列埠工具。某些時候,現有的工具不能滿足需求,於是需要自己開發寫個串列埠小工具,來完成某些操作。windows下串列埠工具的源 很多,有用cserial類的,有用mfc串列埠控制項的。個人感覺,都不是很好用。甚至有時候只要要個命令列下的串列埠工具,不需要介面,敲入不同的...

Windows下串列埠程式設計

造冰箱的大熊貓 cnblogs 2019 1 27 將windows下串列埠程式設計相關資訊進行下簡單小結,以備後用。1 開啟串列埠 開啟串列埠使用createfile 函式。以開啟com6為例 handle hcomm hcomm createfile text com6 generic read...