Win32串列埠程式設計

2021-03-31 08:56:31 字數 3311 閱讀 1307

win32串列埠程式設計

金貝貝

一、基本知識

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

1.dcb配置

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

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

dcb dcb = ;

if (!get***mstate(h***m, &dcb))

// error getting current dcb settings

else

// dcb is ready for use.

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

dcb dcb;

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

dcb.dcblength = sizeof(dcb);

if (!build***mdcb(「9600,n,8,1", &dcb))

else

// dcb is ready for use.

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

dcb dcb;

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

if (!get***mstate(h***m, &dcb)) // get current dcb

// error in get***mstate

return false;

// update dcb rate.

dcb.baudrate = cbr_9600 ;

// set new state.

if (!set***mstate(h***m, &dcb))

// error in set***mstate.

possibly a problem with the ***munications

// 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)通訊事件:用set***mmask()函式設定想要得到的通訊事件的掩碼,再呼叫wait***mevent()函式檢測通訊事件的發生。可設定的通訊事件標誌(即set***mmask()函式所設定的掩碼)可以有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幫助。可以採用迴圈讀的辦法,另外乙個比較好的解決辦法是呼叫clear***merror()函式,確定在一次讀操作中在緩衝區中等待被讀的位元組數。

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

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

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

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

呼叫方法為:closehandle(h***m);

二、實現

1.程式設計思路

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

2.實現細節

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

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

WIN32串列埠程式設計詳解 二

4.2 同步方式讀寫串列埠 下面先例舉同步方式讀寫串列埠的 同步讀串列埠 char str 100 dword wcount 讀取的位元組數 bool breadstat breadstat readfile hcom,str,100,wcount,null if breadstat return ...

WIN32串列埠程式設計詳解 二

4.2 同步方式讀寫串列埠 下面先例舉同步方式讀寫串列埠的 同步讀串列埠 char str 100 dword wcount 讀取的位元組數 bool breadstat breadstat readfile hcom,str,100,wcount,null if breadstat return ...

win32 串列埠 通訊 非同步 執行緒方式

該例子是 visual c 實踐與提高 串列埠通訊與工程應用篇 第2版 書上給出的部分原始碼,整理修改之後的演示 借助 tc35模組可以,正常執行 如下 seritaltk.cpp 定義控制台應用程式的入口點。include stdafx.h include handle hcom dword th...