win32串列埠程式設計**:
韓耀旭)
在工業控制中,工控機(一般都基於windows平台)經常需要與智慧型儀表通過串列埠進行通訊。串列埠通訊方便易行,應用廣泛。
一般情況下,工控機和各智慧型儀表通過rs485匯流排進行通訊。rs485的通訊方式是半雙工的,只能由作為主節點的工控pc機依次輪詢網路上的各智慧型控制單元子節點。每次通訊都是由pc機通過串列埠向智慧型控制單元發布命令,智慧型控制單元在接收到正確的命令後作出應答。
在win32下,可以使用兩種程式設計方式實現串列埠通訊,其一是使用activex控制項,這種方法程式簡單,但欠靈活。其二是呼叫windows的api函式,這種方法可以清楚地掌握串列埠通訊的機制,並且自由靈活。本文我們只介紹api串列埠通訊部分。
串列埠的操作可以有兩種操作方式:同步操作方式和重疊操作方式(又稱為非同步操作方式)。同步操作時,api函式會阻塞直到操作完成以後才能返回(在多執行緒方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽執行緒);而重疊操作方式,api函式會立即返回,操作在後台進行,避免執行緒的阻塞。
無論那種操作方式,一般都通過四個步驟來完成:
(1)開啟串列埠
(2)配置串列埠
(3)讀寫串列埠
(4)關閉串列埠
(1)開啟串列埠
win32系統把檔案的概念進行了擴充套件。無論是檔案、通訊裝置、命名管道、郵件槽、磁碟、還是控制台,都是用api函式createfile來開啟或建立的。該函式的原型為:
handle createfile( lpctstr lpfilename, dword dwdesiredaccess, dword dwsharemode, lpsecurity_attributes lpsecurityattributes, dword dwcreationdistribution, dword dwflagsandattributes, handle htemplatefile);同步i/o方式開啟串列埠的示例**:
handle hcom; //全域性變數,串列埠控制代碼 hcom=createfile("com1",//com1口 generic_read|generic_write, //允許讀和寫 0, //獨佔方式 null, open_existing, //開啟而不是建立 0, //同步方式 null); if(hcom==(handle)-1) return true;重疊i/o開啟串列埠的示例**:
(2)、
配置串列埠
在開啟通訊裝置控制代碼後,常常需要對串列埠進行一些初始化配置工作。這需要通過乙個dcb結構來進行。dcb結構包含了諸如波特率、資料位數、奇偶校驗和停止位數等資訊。在查詢或配置串列埠的屬性時,都要用dcb結構來作為緩衝區。
一般用createfile開啟串列埠後,可以呼叫getcommstate函式來獲取串列埠的初始配置。要修改串列埠的配置,應該先修改dcb結構,然後再呼叫setcommstate函式設定串列埠。
dcb結構包含了串列埠的各項引數設定,下面僅介紹幾個該結構常用的變數:
typedef struct _dcb commtimeouts,*lpcommtimeouts;commtimeouts結構的成員都以毫秒為單位。總超時的計算公式是:
總超時=時間係數×要求讀/寫的字元數+時間常量
例如,要讀入10個字元,那麼讀操作的總超時的計算公式為:
讀總超時=readtotaltimeoutmultiplier×10+readtotaltimeoutconstant
可以看出:間隔超時和總超時的設定是不相關的,這可以方便通訊程式靈活地設定各種超時。
如果所有寫超時引數均為0,那麼就不使用寫超時。如果readintervaltimeout為0,那麼就不使用讀間隔超時。如果readtotaltimeoutmultiplier 和 readtotaltimeoutconstant 都為0,則不使用讀總超時。如果讀間隔超時被設定成maxdword並且讀時間係數和讀時間常量都為0,那麼在讀一次輸入緩衝區的內容後讀操作就立即返回,而不管是否讀入了要求的字元。
在用重疊方式讀寫串列埠時,雖然readfile和writefile在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是readfile和writefile的返回時間。
配置串列埠的示例**:
setupcomm(hcom,1024,1024); //輸入緩衝區和輸出緩衝區的大小都是1024 commtimeouts timeouts; //設定讀超時 timeouts.readintervaltimeout=1000; timeouts.readtotaltimeoutmultiplier=500; timeouts.readtotaltimeoutconstant=5000; //設定寫超時 timeouts.writetotaltimeoutmultiplier=500; timeouts.writetotaltimeoutconstant=2000; setcommtimeouts(hcom,&timeouts); //設定超時 dcb dcb; getcommstate(hcom,&dcb); dcb.baudrate=9600; //波特率為9600 dcb.bytesize=8; //每個位元組有8位 dcb.parity=noparity; //無奇偶校驗位 dcb.stopbits=twostopbits; //兩個停止位 setcommstate(hcom,&dcb); purgecomm(hcom,purge_txclear|purge_rxclear);在讀寫串列埠之前,還要用purgecomm()函式清空緩衝區,該函式原型:
bool purgecomm( handle hfile, //串列埠控制代碼 dword dwflags // 需要完成的操作 );引數dwflags指定要完成的操作,可以是下列值的組合:
purge_txabort 中斷所有寫操作並立即返回,即使寫操作還沒有完成。 purge_rxabort 中斷所有讀操作並立即返回,即使讀操作還沒有完成。 purge_txclear 清除輸出緩衝區 purge_rxclear 清除輸入緩衝區(3)、
讀寫串列埠
我們使用readfile和writefile讀寫串列埠,下面是兩個函式的宣告:
//同步讀串列埠 char str[100]; dword wcount;//讀取的位元組數 bool breadstat; breadstat=readfile(hcom,str,100,&wcount,null); if(!breadstat) return true; //同步寫串列埠 char lpoutbuffer[100]; dword dwbyteswrite=100; comstat comstat; dword dwerrorflags; bool bwritestat; clearcommerror(hcom,&dwerrorflags,&comstat); bwritestat=writefile(hcom,lpoutbuffer,dwbyteswrite,& dwbyteswrite,null); if(!bwritestat) purgecomm(hcom, purge_txabort| purge_rxabort|purge_txclear|purge_rxclear);
對以上**再作簡要說明:在使用readfile 函式進行讀操作前,應先使用clearcommerror函式清除錯誤。clearcommerror函式的原型如下:
bool clearcommerror( handle hfile, // 串列埠控制代碼 lpdword lperrors, // 指向接收錯誤碼的變數 lpcomstat lpstat // 指向通訊狀態緩衝區 );該函式獲得通訊錯誤並報告串列埠的當前狀態,同時,該函式清除串列埠的錯誤標誌以便繼續輸入、輸出操作。
引數lpstat指向乙個comstat結構,該結構返回串列埠狀態資訊。 comstat結構 comstat結構包含串列埠的資訊,結構定義如下:
typedef struct _comstat comstat, *lpcomstat;本文只用到了cbinque成員變數,該成員變數的值代表輸入緩衝區的位元組數。
最後用purgecomm函式清空串列埠的輸入輸出緩衝區。
非同步寫串列埠的示例**:
(4)、
關閉串列埠
利用api函式關閉串列埠非常簡單,只需使用createfile函式返回的控制代碼作為引數呼叫closehandle即可:
bool closehandle(
handle hobject; //handle to object to close
);
VC 串列埠通訊程式設計詳解
總結來看串列埠通訊原理,也可以說大多數通訊原理也是如此 通訊首先要有個通訊,可以簡單的把通訊看成乙個小桶,傳送方住水桶裡裝水,接收方從水桶中取水。如果你要和對方通訊首先需要將桶蓋開啟,再將水裝入到桶中,這時接收方才能夠從桶中取到水。這裡就存在著一定的問題,1,如果桶蓋還沒有開啟,傳送方已經傳送了。這...
VC串列埠程式設計
本文 1 api描述 在win32 api 中,串列埠使用檔案方式進行訪問,其操作的 api基本上與檔案操作的 api一致。一 開啟串列埠 win32 中用於開啟串列埠的api 函式為createfile,其原型為 例如,以下程式用於以同步讀寫方式開啟串列埠com1 handle hcom dwor...
VC 的串列埠通訊
vc 的串列埠通訊 vc 的串列埠通訊 代翔在vc 中有兩種方法可以進行串列埠通訊。一種是利用microsoft公司提供的activex 控制項 microsoft communications control。另一種是直接用vc 訪問串列埠。下面將簡述 這兩種方法。一 microsoft comm...