VC串列埠通訊程式設計

2021-06-09 21:00:49 字數 4153 閱讀 1086

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...