深入淺出VC 串列埠程式設計之基於Win32 API

2021-04-09 10:18:04 字數 4453 閱讀 7078

1、api描述

在win32 api中,串列埠使用檔案方式進行訪問,其操作的api基本上與檔案操作的api一致。

開啟串列埠

win32 中用於開啟串列埠的api 函式為createfile,其原型為:

例如,以下程式用於以同步讀寫方式開啟串列埠com1:

handle hcom;

dword dwerror;

hcon = createfile("com1", generic_read | generic_write, 0, null, open_existing, 0, null);

if (hcom == (handle)0xffffffff)

配置串列埠

配置串列埠是通過改變裝置控制塊dcb(device control block) 的成員變數值來實現的,接收緩衝區和傳送緩衝區的大小可通過setupcomm函式來設定。

dcb結構體定義為:

typedef struct _dcb dcb;

而setupcomm函式的原型則為:

bool setupcomm(

handle hfile, // handle to communications device

dword dwinqueue, // size of input buffer

dword dwoutqueue // size of output buffer);

以下程式將串列埠設定為:波特率為9600,資料位數為7位,停止位為2 位,偶校驗,接收緩衝區和傳送緩衝區大小均為1024個位元組,最後用purgecomm函式終止所有的後台讀寫操作並清空接收緩衝區和傳送緩衝區:

dcb dcb;

dcb.baudrate = 9600; //波特率為9600

dcb.bytesize = 7; //資料位數為7位

dcb.parity = evenparity; //偶校驗

dcb.stopbits = 2; //兩個停止位

dcb.fbinary = true;

dcb.fparity = true;

if (!setcommstate(hcom, &dcb))

setupcomm(hcom, 1024, 1024);

purgecomm(hcom, purce_txabort | purge_rxabort | purge_txclear | purge_rxclear);

超時設定

超時設定是通過改變commtimeouts結構體的成員變數值來實現的,commtimeouts的原型為:

typedef struct _commtimeouts

commtimeouts, *lpcommtimeouts;

設定超時的函式為setcommtimeouts,其原型中接收commtimeouts的指標為引數:

bool setcommtimeouts(

handle hfile, // handle to communications device

lpcommtimeouts lpcommtimeouts // pointer to comm time-out structure);

以下程式將串列埠讀操作的超時設定為10 毫秒:

commtimeouts to;

memset(&to, 0, sizeof(to));

to.readintervaltimeout = 10;

setcommtimeouts(hcom, &to);

與setcommtimeouts對應的getcommtimeouts()函式的原型為:

bool getcommtimeouts(

handle hfile, // handle of communications device

lpcommtimeouts lpcommtimeouts // pointer to comm time-out structure);

事件設定

在讀寫串列埠之前,需要用setcommmask ()函式設定事件掩模來監視指定通訊埠上的事件,其原型為:

bool setcommmask(

handle hfile, //標識通訊埠的控制代碼

dword dwevtmask //能夠使能的通訊事件);

有了set當然還會有get,與setcommmask對應的getcommmask()函式的原型為:

bool getcommmask(

handle hfile, //標識通訊埠的控制代碼

lpdword lpevtmask // address of variable to get event mask);

串列埠上可以發生的事件可以是如下事件列表中的乙個或任意組合:ev_break、ev_cts、ev_dsr、ev_err、ev_ring、ev_rlsd、ev_rxchar、ev_rxflag、ev_txempty。

我們可以用waitcommevent()函式來等待串列埠上我們利用setcommmask ()函式設定的事件:

waitcommevent()函式一直阻塞,直到串列埠上發生我們用所setcommmask ()函式設定的通訊事件為止。一般而言,當waitcommevent()返回時,程式設計師可以由分析*lpevtmask而獲得發生事件的類別,再進行相應的處理。

讀串列埠對串列埠進行讀取所用的函式和對檔案進行讀取所用的函式相同,讀函式原型如下:

寫串列埠

對串列埠進行寫入所用的函式和對檔案進行寫入所用的函式相同,寫函式原型如下:

關閉串列埠

利用api 函式實現串列埠通訊時關閉串列埠非常簡單,只需使用createfile 函式返回的控制代碼作為引數呼叫closehandle 即可:

bool closehandle(

handle hobject // handle to object to close);

2.例程

在筆者的《

深入淺出win32多執行緒程式設計之綜合例項

》中我們已經給出乙個利用win api進行串列埠通訊的例子,這裡再給出乙個類似的例子,以進一步加深理解。

對話方塊上控制項對應的資源檔案(.rc)中的內容如下:

begin

edittext idc_recv_edit,28,119,256,46,es_autohscroll

groupbox "傳送資料",idc_static,19,15,282,70

groupbox "接收資料",idc_static,19,100,282,80

edittext idc_send_edit,29,33,214,39,es_autohscroll

pushbutton "清除",idc_clear_button,248,33,50,14

pushbutton "傳送",idc_send_button,248,55,50,14

end

而整個對話方塊的訊息對映(描述了訊息及其對應的行為)如下:

begin_message_map(cserialportapidlg, cdialog)

//}afx_msg_map

end_message_map()

在對話方塊的oninitdialog()函式中,我們啟動視窗監聽執行緒並將主視窗控制代碼傳遞給執行緒控制函式:

在工程中新增serialportcontrol.h和serialportcontrol.cpp兩個檔案,前者宣告串列埠控制的介面函式及外部全域性變數,後者實現串列埠介面函式及串列埠監聽執行緒控制函式。

serialportcontrol.h檔案

#ifndef _serial_port_control_h

#define _serial_port_control_h

#define com_recvdata wm_user+1000//自定義訊息

extern handle hcom; //全域性變數,串列埠控制代碼

extern handle hcommthread; //全域性變數,串列埠線程

//串列埠監視執行緒控制函式

extern dword winapi serialport1threadprocess(hwnd hwnd);

//開啟並設定pc串列埠1(com1)

extern bool openserialport1();

#endif

serialportcontrol.cpp檔案

#include "stdafx.h"

#include "serialportcontrol.h"

handle hcom; //全域性變數,串列埠控制代碼

handle hcommthread; //全域性變數,串列埠線程

bool openserialport1()

else

return true;

}//以乙個執行緒不同監控串列埠行接收的資料

dword winapi serialport1threadprocess( hwnd hwnd//主視窗控制代碼)

}return true;}

為了驗證程式的正確性,我們使用串列埠除錯助手與本程式協同工作,互相進行收發。下面的抓圖顯示本程式工作正確,傳送和接收字元準確無誤。

深入淺出VC 串列埠程式設計 基於控制項

visual c 為我們提供了一種好用的activex控制項microsoft communications control 即mscomm 來支援應用程式對串列埠的訪問,在應用程式中插入mscomm控制項後就可以較為方便地實現對通過計算機串列埠收發資料。要使用activex控制項mscomm,程式...

深入淺出VC 串列埠程式設計之基於Win32 API

1 api描述 在win32 api中,串列埠使用檔案方式進行訪問,其操作的api基本上與檔案操作的api一致。開啟串列埠 win32 中用於開啟串列埠的api 函式為createfile,其原型為 例如,以下程式用於以同步讀寫方式開啟串列埠com1 handle hcom dword dwerro...

深入淺出VC 串列埠程式設計之基於Win32 API

1 api描述 在win32 api中,串列埠使用檔案方式進行訪問,其操作的api基本上與檔案操作的api一致。開啟串列埠 win32 中用於開啟串列埠的api 函式為createfile,其原型為 例如,以下程式用於以同步讀寫方式開啟串列埠com1 handle hcom dword dwerro...