999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

在VC++下用Win32 API函數編寫多線程串口通信程序

2009-02-01 03:29:48
數字技術與應用 2009年12期

金 劍

[摘 要]介紹了使用32位Windows API函數編寫串口通信程序的方法,采用多線程和事件驅動技術,使所編寫的程序運行效率較高,對于CPU任務比較繁重的PC機—單片機工業控制系統的性能提高有很大意義。

[關鍵詞]VC++ Win32 API 串口通信 多線程

[中圖分類號][文獻標識碼]A[文章編號]1007-9416(2009)12-0024-02

1 引言

Windows環境下編程的最大特點就是設備無關性,通過驅動程序將應用程序與外部設備相隔離。Windows封裝了通信機制,稱為通信API,程序員可以利用它間接控制通信端口,不必對硬件進行直接操作。目前采用Microsoft公司提供的ActiveX控件MSComm實現串口通信的實例相當多,使用也非常簡單,但是由于只能在對話框應用程序中使用,應用范圍有限,而采用API函數編程就完全避免了這個問題。

線程是操作系統分配CPU時間的基本單位,系統不停地在各個線程之間切換,一個線程只有在分配的時間片內才對CPU有控制權。利用Win32系統的多線程特性,主線程負責與用戶進行交互,設置輔助線程專門負責通信I/O,程序員就可以編寫出準實時的“兩不誤”通信程序。

很多工業控制系統中常常通過串口連接外設,而各外設發送數據重復的頻率不同,要求應用程序后臺實時無差錯地捕捉和處理各端口數據,同時前臺仍舊可以與用戶進行交互,我們可以在VC++環境下,用Win32通信API及多線程技術編寫高效率的通信程序來完成這一任務,開發過程如下。

2 打開串口

Win32系統中,串口是作為文件處理的,其打開、關閉、讀取和寫入所用的函數與文件操作函數完全一致。通信會話以調用CreateFile()函數開始,描述如下。

HANDLE hCom;//定義端口句柄

hCom=CreateFile(“Com1”,//以字符串形式指定要打開的串口名

GENERIC_READ|GENERIC_WRITE,//指定訪問類型,允許讀和寫

0,//指定共享屬性。對于串口,必須設置為0,表示獨占

NULL,//引用安全屬性結構。設為NULL為串口分配缺省的安全屬性

OPEN_EXISTING,//告訴Windows打開已經存在的端口

FILE_FLAG_OVERLAPPED,//指定端口I/O可以在后臺進行,即異步I/O

NULL//設定指向模板文件的句柄,對于串口,必須設置成NULL);

If(hCom==INVALID_HANDLE_VALUE){…}//未成功打開串口,編寫異常處理程序。

3 配置串口

在CreateFile()成功調用打開串口后,Windows將根據上次打開串口時的設置來初始化端口,如果是首次打開,系統將使用缺省的配置。

3.1 為端口分配緩沖區

SetupComm(hCom,//已經打開的端口句柄,下同

1024,//以字節數指定輸入緩沖區大小

1024,//以字節數指定輸入緩沖區大小);

3.2 清空緩沖區

PurgeComm(hCom,

PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

PurgeComm()函數的第二個參數指定動作,其設定值如表1所示:

3.3 設置驅動事件類型

SetCommMask(hCom,

EV_RXCHAR//設定被監視的通信事件,見表2);

3.4 定義并設置超時結構變量

COMMTIMEOUTS CommTimeOuts;

……//填寫超時結構

SetCommTimeOuts(hCom, &CommTimeOuts;);//應用設置好的超時結構

超時結構是Windows針對串口讀寫引入的數據結構,直接影響讀和寫的操作行為,定義如下:

typedef struct_COMMTIMEOUTS{

DWORD ReadIntervalTimeout;//以ms為單位指定兩個字符到達的最大時間間隔

DWORD ReadTotalTimeoutMultiplier;//以ms為單位指定計算讀操作總超時時間的系數

DWORD ReadTotalTimeoutConstant; //以ms為單位指定常數,也用于計算讀操作超時時間

DWORD WriteTotalTimeoutMultiplier;//以ms為單位指定計算寫操作總超時時間的系數

DWORD WriteTotalTimeoutConstant; //以ms為單位指定常數,也用于計算寫操作超時時間

}COMMTIMEOUTS,*LPCOMMTIMEOUTS;

Windows按如下式子計算總超時時間,可根據具體應用情況設定超時結構的參數:

ReadTotalTimeout=ReadTotalTimeoutMultiplier*bytes_to_read+ReadTotalTimeoutConstant;

WriteTotalTimeout=WriteTotalTimeoutMultiplier*bytes_to_write+WriteTotaltimeoutConstant;

3.5 定義并設置設備控制塊DCB

DCB dcb;

GetCommState(hCom,&dcb;);//獲取當前的DCB狀態參數

dcb.BaudRate=9600;//設定波特率

dcb.ByteSize=8;//設定端口使用的數據位數

dcb.Parity=NOPARITY;//設定奇偶校驗方法,此處設為無校驗

dcb.StopBits=ONESTOPBIT;//設定端口使用的停止位位數,此處設為1位停止位

dcb.fBinary=TRUE;//允許二進制。Win32不支持非二進制傳輸,此處必須設為TRUE

dcb.fParity=FALSE;//指定是否允許奇偶校驗,此處設為禁止奇偶校驗

SetCommState(hCom,&dcb;);//應用配置好的參數

4 啟動輔助線程

CWinThread*m_pThread;//定義線程類變量

……//啟動輔助線程

m_pThread=AfxBeginThread(CommWatchProc,//指定線程處理函數名

this,//設置要傳遞給線程函數的參數

THREAD_RPIORITY_NORMAL,//設定優先級微調值

0,//設置默認的堆棧大小(1MB)

CREATE_SUPSPENDED,//掛起創建好的線程

NULL//安全防護屬性,NULL表示這一屬性與其產生者相同);

if(m_pThread= =NULL)CloseHandle(m_hCom);//未成功創建,關閉串口

elsem_pThread ->ResumeThread();//成功創建,恢復線程的運行

//線程函數

UNIT CommWatchProc(HWND hSendWnd)//傳入的參數是欲投放消息的目的窗口的句柄

{ OVERLAPPED os;

DWORD dwEvtMask=0;//用于記錄事件掩模

COMSTAT ComStat;//COMSTAT結構存放通信設備的當前信息,由ClearCommError函數填寫

DWORD dwErrorFlag;

BOOL fReadStat;//記錄返回的讀狀態

while(TRUE){//循環監測串口事件

WaitCommEvent(hCom, &dwEvtMask;,&os;);//等待串口通信事件的發生

//檢測返回的dwEvtMask,從而判定發生了何種串口事件

if((dwEvtMask & EV_RXCHAR)==EV_RXCHAR){//緩沖區有數據到達

ClearCommError(hCom, &dwErrorFlag;, &ComStat;);//清除錯誤條件,確定串口狀態

if(ComStat.cbInQue){//如果串口接收到的字節數不為0,就讀取數據

fReadStat=ReadFile(hCom,

buffer,//指向一個緩沖區

length,//指定要從串口讀取的字節數

&length;,//指向調用該函數讀出的字節數

&os;_Read//指向一個OVERLAPPED結構);

if(!fReadStat)//函數返回時I/O操作尚未完成

//等待重疊操作結果,直到完成異步I/O

GetOverlappedResult(hCom,&os;,&length;,TRUE);

else

return(UNIT)-1;

}

}

PostMessage(hSendWnd,WM_COMMNOTIFY,EV_RXCHAR,0);//發送消息

}

}

5 編寫發送命令

BOOL fWriteStat;

char szBuffer[SENDBLOCK];

……//將待發送的數據放在szBuffer[ ]中

//將數據寫入串口

fWriteStat=WriteFile(hCom,szBuffer, dwBytesToWrite,&dwBytesToWrite;,os_WRITE);

if(!fWriteStat)

if(GetLastError( )==ERROR_IO_PENDING)

//等待重疊操作結果

GetOverlappedResult(hCom,&os;_WRITE,&length;,TRUE);

在整個程序中,OVERLAPPED是個非常重要的結構,用于設置異步I/O。要使用OVERLAPPED結構,CreatFile( )函數的第六個參數必須設置FILE_FLAG_OVERLAPPED標識,同時串口讀寫函數ReadFile( )和WriteFile( )的第五個參數也必須指定VOERLAPPED結構,否則函數不會正確地報告I/O操作已經完成。

串口使用完畢后必須調用CloseHandle( )函數將其關閉,否則串口會繼續保持打開狀態,其它程序將無法使用。最后還要編寫WM_COMMNOTIFY消息的處理函數,可根據具體的工程應用情況靈活處理,在此就不贅述了。

6 結語

Windows為串口通信提供了完善的接口函數,再利用VC++這個強大的編程開發環境,就使得廣大工程技術人員可以輕松地編寫出界面友好而高效的通信程序,來解決工業控制領域的許多技術問題。

參考文獻

[1] 李現勇.Visual C++串口通信技術與工程實踐.人民郵電出版社,2002年5月.

[2] Charles Wright著,鄧勁生,張曉明譯.Visual C++程序員使用大全.中國水利水電出版社,2001年10月.

[3] 伍紅兵.Visual C++編程深入引導.中國水利水電出版社,2002年3月.

主站蜘蛛池模板: 免费看美女毛片| 国产一级无码不卡视频| 久久狠狠色噜噜狠狠狠狠97视色| 色网站免费在线观看| 日韩免费毛片| 亚洲欧美日韩成人在线| 国产精品美乳| 毛片免费网址| 91年精品国产福利线观看久久 | 久久精品无码一区二区日韩免费| 精品国产香蕉伊思人在线| 国产国产人成免费视频77777| 2020最新国产精品视频| 国产精品人莉莉成在线播放| 久久频这里精品99香蕉久网址| 久久综合干| 99视频免费观看| 奇米精品一区二区三区在线观看| 亚洲Av综合日韩精品久久久| 色网在线视频| 午夜综合网| 国产九九精品视频| 亚洲第一区欧美国产综合| 亚洲第一黄色网| 国产激爽大片在线播放| 成色7777精品在线| 婷婷色一区二区三区| 欧美区一区| 免费中文字幕一级毛片| 中文字幕乱码中文乱码51精品| 亚洲国产91人成在线| 国产裸舞福利在线视频合集| 人人妻人人澡人人爽欧美一区| 波多野结衣一二三| 亚洲天堂视频在线免费观看| 久久 午夜福利 张柏芝| 国产在线小视频| 欧美啪啪视频免码| 国产在线小视频| 女人毛片a级大学毛片免费| 国产毛片高清一级国语| 在线看片中文字幕| 亚洲IV视频免费在线光看| 制服丝袜 91视频| 国产剧情国内精品原创| 免费看黄片一区二区三区| 亚洲视频免费播放| 国产美女久久久久不卡| 亚洲AV无码不卡无码| 青青草原国产av福利网站| 久久夜色撩人精品国产| 熟女视频91| 亚洲综合色婷婷中文字幕| 国产免费人成视频网| 免费Aⅴ片在线观看蜜芽Tⅴ| 日韩无码视频网站| 国产亚洲欧美在线中文bt天堂 | 91系列在线观看| 国产一区二区三区免费观看 | 无码粉嫩虎白一线天在线观看| 综合五月天网| 国产精品黑色丝袜的老师| 91青青草视频| 久久免费视频播放| 91精品国产91久久久久久三级| 99免费视频观看| 国产亚洲精品无码专| 色婷婷电影网| 超碰色了色| 亚洲精品在线影院| 久久久久无码精品国产免费| 亚洲日韩精品无码专区97| 亚洲综合天堂网| 欧美成人二区| julia中文字幕久久亚洲| 在线视频精品一区| 久久99国产综合精品1| 99精品热视频这里只有精品7| 无码专区国产精品第一页| 91久久精品日日躁夜夜躁欧美| 亚洲一区网站| www精品久久|