本文介紹了在Microsoft Visual C++ 6.0環(huán)境下對(duì)RS-232-C串行端口進(jìn)行編程,以及對(duì)后臺(tái)監(jiān)控程序所普遍涉及到的無(wú)阻塞后臺(tái)運(yùn)行、數(shù)據(jù)的實(shí)時(shí)接收和處理等問(wèn)題的解決方法。
一、 引言
在實(shí)驗(yàn)室和工業(yè)應(yīng)用中,受信道成本限制,串口常常作為計(jì)算機(jī)與外部串行設(shè)備之間的首選數(shù)據(jù)傳輸通道,而且由于串行通信方便易行,許多設(shè)備和計(jì)算機(jī)都可以通過(guò)串口對(duì)外設(shè)進(jìn)行控制、檢測(cè),串口通訊日益成為計(jì)算機(jī)和外設(shè)進(jìn)行通訊、獲取由外設(shè)采集到的監(jiān)測(cè)數(shù)據(jù)的一個(gè)非常重要的手段。本文所描述的程序?qū)嵗\(yùn)行于Windows 9x操作系統(tǒng)下,可后臺(tái)運(yùn)行、實(shí)時(shí)接收、處理從端口傳來(lái)的數(shù)據(jù),并能通過(guò)向串口發(fā)送命令來(lái)控制外設(shè)的動(dòng)作。為了避免在實(shí)時(shí)監(jiān)控?cái)?shù)據(jù)時(shí)引發(fā)程序阻塞,在本程序中引入了線(xiàn)程和端口中斷響應(yīng)等技術(shù)。
二、 程序設(shè)計(jì)思路
由于本程序要對(duì)串行端口進(jìn)行實(shí)時(shí)監(jiān)控,這就要求它是一個(gè)后臺(tái)程序,在監(jiān)控的同時(shí)可以在前臺(tái)進(jìn)行其他一些于之無(wú)關(guān)的操作。因而在實(shí)現(xiàn)時(shí)即要避免無(wú)時(shí)無(wú)刻都在反復(fù)讀端口的效率低下的輪詢(xún)方式,又不能因?yàn)閬?lái)不及處理而將突然到達(dá)的監(jiān)測(cè)數(shù)據(jù)丟失。只有采取端口中斷的異步方式才能實(shí)現(xiàn)高效、安全的監(jiān)控過(guò)程,只要一有數(shù)據(jù)到達(dá)端口,馬上拋出中斷請(qǐng)求,中斷處理函數(shù)便會(huì)及時(shí)啟動(dòng)以處理到來(lái)的數(shù)據(jù),從而避免了輪詢(xún)間隙丟時(shí)數(shù)據(jù)的可能。而在大部分無(wú)數(shù)據(jù)到達(dá)的時(shí)間內(nèi)不會(huì)有中斷拋出,中斷處理函數(shù)也不會(huì)執(zhí)行,即僅僅在有數(shù)據(jù)到達(dá)的一瞬間進(jìn)行工作,此效率不可謂不高。
綜上所述,要實(shí)現(xiàn)上述要求,就要用到下列技術(shù)來(lái)解決所遇到的關(guān)鍵性問(wèn)題:一是采用多線(xiàn)程來(lái)避免在進(jìn)行文件操作等耗時(shí)操作時(shí)會(huì)引發(fā)阻塞現(xiàn)象的發(fā)生。同時(shí)為了防止多個(gè)線(xiàn)程同時(shí)對(duì)同一個(gè)變量進(jìn)行操作引起時(shí)序上的差錯(cuò),為了保持線(xiàn)程的同步,還采取了臨界區(qū)加解鎖的技術(shù);二是對(duì)端口的數(shù)據(jù)讀取方式采取中斷響應(yīng)模式,具體原因前面以講的很清楚,在此不再贅述;三是使用了定時(shí)器,以滿(mǎn)足實(shí)時(shí)監(jiān)控類(lèi)程序的實(shí)時(shí)顯示功能,以便及時(shí)的將所接收到的動(dòng)態(tài)數(shù)據(jù)及時(shí)的反映到屏
幕上。
三、 RS-232-C串行端口監(jiān)控軟件的程序?qū)崿F(xiàn)
(一) 界面風(fēng)格
由于是實(shí)時(shí)監(jiān)控軟件,那就既要監(jiān)測(cè)從外設(shè)傳來(lái)的實(shí)時(shí)數(shù)據(jù),又要通過(guò)串口向外設(shè)發(fā)送一些具體的指令以控制外設(shè)完成預(yù)先設(shè)定的動(dòng)作。為了方便向串口發(fā)送命令可以在工具條上再加一個(gè)類(lèi)似于"Internet Explorer 瀏覽器"風(fēng)格的對(duì)話(huà)條,可以在初建工程時(shí)指定"Internet Explorer ReBars"風(fēng)格,也可以通過(guò)添加Microsoft Visual C++ 6.0自帶的"Dialog Bar"組件來(lái)實(shí)現(xiàn)。而要及時(shí)將從外部讀取的數(shù)據(jù)顯示給管理人員,并且留有相當(dāng)記錄以備查閱,可以選擇列表視圖來(lái)實(shí)現(xiàn)。
(二) 串口的參數(shù)設(shè)置及打開(kāi)
對(duì)RS-232-C串行端口進(jìn)行參數(shù)配置是使用串口進(jìn)行通訊的必要條件。而且由于場(chǎng)合不同、用途、功能的不同對(duì)串口也采取不同的配置方式,為了使本程序更靈活,適應(yīng)面更廣,采取將所有的可能參數(shù)都預(yù)先設(shè)置在幾個(gè)組合框中,可以在程序運(yùn)行后隨時(shí)更改設(shè)置。自定義一個(gè)設(shè)置串口參數(shù)的數(shù)據(jù)結(jié)構(gòu):
typedef struct tagCOM_CONFIG |
當(dāng)選擇好適當(dāng)?shù)膮?shù)后就可以根據(jù)設(shè)置好的端口配置情況打開(kāi)通訊端口了。與以往DOS下串行通信程序不同的是,Windows操作平臺(tái)下不提倡應(yīng)用程序直接控制硬件(包括端口),也不讓使用中斷(除非打入到Ring0系統(tǒng)級(jí)),而是通過(guò)Windows操作系統(tǒng)提供的設(shè)備驅(qū)動(dòng)程序來(lái)進(jìn)行數(shù)據(jù)傳遞。在Windows操作系統(tǒng)下串行口和其他通訊端口一樣是作為文件來(lái)進(jìn)行處理的,而不是直接對(duì)端口進(jìn)行操作,對(duì)于串行通信,Win 32 提供了相應(yīng)的文件I/O函數(shù)與通信函數(shù),通過(guò)了解這些函數(shù)的使用,可以編制出符合不同需要的通信程序。與通信設(shè)備相關(guān)的結(jié)構(gòu)有COMMCONFIG ,COMMPROP,COMMTIMEOUTS,COMSTAT,DCB,MODEMDEVCAPS,MODEMSETTINGS共7個(gè),與通信有關(guān)的Windows API函數(shù)共有26個(gè),具體說(shuō)明可參考MSDN幫助文件。下面是打開(kāi)串口的部分關(guān)鍵代碼:
//以創(chuàng)建文件的形式打開(kāi)文件,并將返回的端口句柄保存于句柄idComDev之中。 |
(三) 偵聽(tīng)監(jiān)視線(xiàn)程
當(dāng)成功的打開(kāi)端口之后通過(guò)執(zhí)行線(xiàn)程開(kāi)啟函數(shù)AfxBeginThread(COMReadThreadProc,NULL,THREAD_PRIORITY_NORMAL);開(kāi)啟了一個(gè)用于偵聽(tīng)端口的工作線(xiàn)程COMReadThreadProc。其具體處理過(guò)程
如下:





