摘要:該文結(jié)合應(yīng)用實(shí)際介紹了在Dos下串口高速中斷的處理辦法,彌補(bǔ)了現(xiàn)有資料在高速串口中斷時(shí)會(huì)丟失數(shù)據(jù)的不足。
關(guān)鍵詞:DOS;串口;高速中斷;中斷服務(wù)程序
中圖分類號(hào):TP316 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2012)28-6702-03
串行接口設(shè)備憑借其控制靈活、接口簡(jiǎn)單、占用系統(tǒng)資源少等優(yōu)點(diǎn),被廣泛應(yīng)用于工業(yè)控制、家庭安防、GPS衛(wèi)星定位導(dǎo)航等領(lǐng)域。在這些嵌入式系統(tǒng)中,可能會(huì)有很多從設(shè)備都通過(guò)串行接口與主機(jī)進(jìn)行通信。
本文中系統(tǒng)軟件通過(guò)串口來(lái)向外發(fā)送控制數(shù)據(jù)。控制機(jī)為x86架構(gòu)的計(jì)算機(jī),操作系統(tǒng)為MS-DOS6.22。由于系統(tǒng)中數(shù)據(jù)傳輸距離比較遠(yuǎn),超過(guò)了232串口的最大傳輸距離。所以需要使用差分串口來(lái)提高傳輸距離,這就需要我們使用第三方提供的串口擴(kuò)展卡,在系統(tǒng)中擴(kuò)展出兩個(gè)422串口。我們使用中斷方式來(lái)處理串口收發(fā)的數(shù)據(jù)。這種辦法相比起查詢方式來(lái)可以大大的節(jié)省CPU時(shí)間,使CPU可以省出時(shí)間來(lái)干別的事。
本文中的串口數(shù)據(jù)傳輸速度非常快,這就使得中斷被觸發(fā)的頻率很快。剛開始我們根據(jù)專門講串口編程的書[1]和網(wǎng)上查到的資料來(lái)編程。調(diào)試的時(shí)候發(fā)現(xiàn)有數(shù)據(jù)丟失的現(xiàn)象。進(jìn)一步探查發(fā)現(xiàn)數(shù)據(jù)丟失是由于有些串口中斷丟失了,數(shù)據(jù)沒有被處理。經(jīng)過(guò)不斷的探查,我們終于找到了解決串口中斷丟失問題的辦法。下面按照編程的步驟一步一步來(lái)進(jìn)行說(shuō)明。
1 軟件實(shí)現(xiàn)
1.1 串口初始化
首先需要對(duì)串口進(jìn)行初始化,設(shè)置數(shù)據(jù)位,停止位和波特率。COM端口的寄存器組如表1所示,共有12個(gè)寄存器,使用了8個(gè)地址,其中部分寄存器共用一個(gè)地址,由DLAB=0/1來(lái)區(qū)分。DLAB是線路控制寄存器的第7位。根據(jù)下表所示的線路控制寄存器相對(duì)于串口基地址的偏移3來(lái)訪問它。首先設(shè)置允許訪問波特率寄存器,再根據(jù)表2線路控制寄存器各位的意義來(lái)設(shè)置波特率,最后再設(shè)置停止位和數(shù)據(jù)位。源代碼如下所示。
1.2 中斷編程
首先需要掛接中斷,使得pc機(jī)在中斷觸發(fā)以后可以調(diào)用我們的中斷處理程序。這分為以下幾步,
1)使用dos系統(tǒng)調(diào)用_dos_getvect[3]函數(shù),把我們的中斷處理函數(shù)(本文中為int_COM)掛接到相應(yīng)的中斷向量上,本文中為IRQ12。
2)對(duì)系統(tǒng)中的8259中斷管理器進(jìn)行設(shè)置,在其中打開串口對(duì)應(yīng)中斷的屏蔽位,以使pc機(jī)不會(huì)屏蔽串口中斷。
3)需要通過(guò)串口的中斷允許寄存器來(lái)設(shè)置我們想要響應(yīng)的串口中斷,比如接受中斷、發(fā)送中斷還是兩者都響應(yīng)等等。
源代碼如下:
1.3 編寫中斷服務(wù)程序
中斷服務(wù)程序的編寫是本文的關(guān)鍵,做本項(xiàng)目的時(shí)候參考了大量介紹串口編程的專業(yè)書籍,其中介紹的串口中斷服務(wù)程序的寫法大同小異,按照其方法來(lái)寫中斷服務(wù)程序,在傳輸數(shù)據(jù)量大,中斷頻率高的時(shí)候就會(huì)頻繁的出現(xiàn)數(shù)據(jù)丟失的現(xiàn)象。這說(shuō)明這種寫法是有問題的。按照書上的說(shuō)法,串口在接收數(shù)據(jù)的時(shí)候每收到一個(gè)字符,中斷就會(huì)被觸發(fā)一次,這樣只需在串口中斷服務(wù)程序里每次判斷這個(gè)中斷是否是接收中斷,如果是的話,就讀取一個(gè)字符數(shù)據(jù),這樣就可以了。但是我們?cè)趯?shí)際中發(fā)現(xiàn)經(jīng)常會(huì)出現(xiàn)中斷服務(wù)函數(shù)被調(diào)用一次就可能會(huì)有多個(gè)字符被接收進(jìn)來(lái)的情況。解決這個(gè)問題的關(guān)鍵是中斷服務(wù)程序要象下面源代碼所示,在程序中把中斷處理程序中處理接收部分括進(jìn)一個(gè)while(1)循環(huán)。這樣在接受完一個(gè)字符后,程序會(huì)再次檢查中斷識(shí)別寄存器,看看是否又接受到字符了,直到確認(rèn)沒有數(shù)據(jù)了,也沒有發(fā)送中斷的時(shí)候程序才會(huì)從return處退出。而根據(jù)現(xiàn)有的資料來(lái)編寫中斷服務(wù)程序,就相當(dāng)于是沒有while(1)循環(huán)的語(yǔ)句,中斷觸發(fā)以后程序判斷是否是接收中斷,如果是就讀取一個(gè)字符數(shù)據(jù),完后就退出中斷服務(wù)程序。跟前一種寫法相比顯然會(huì)少接收到一些字符。這已經(jīng)被本項(xiàng)目實(shí)際所證明。
2 結(jié)論
本文中所介紹的雖然是DOS下串口的編程,但是編寫方法是直接端口訪問,所以其方法也適用于其它操作系統(tǒng),如vworks等。關(guān)于中斷的一些看法,如“在實(shí)際中發(fā)現(xiàn)經(jīng)常會(huì)出現(xiàn)中斷服務(wù)函數(shù)被調(diào)用一次就可能會(huì)有多個(gè)字符被接收進(jìn)來(lái)的情況”,也同樣適用于其它在x86架構(gòu)下的中斷處理。具有一定的普遍意義。
參考文獻(xiàn):
[1] 龔建偉,熊光明.串口通信編程實(shí)踐[M].北京:電子工業(yè)出版社,2005:169-195.
[2] 羅利.基于中斷方式PC104 高速串行通訊軟件[J].電子測(cè)量技術(shù),2004(4):110-112.
[3] 劉甲耀,嚴(yán)桂蘭.TURBOC 語(yǔ)言程序設(shè)[M].北京:電子工業(yè)出版社,199