Windows 中斷程序設(shè)計(jì)
掛住/解掛中斷向量的時(shí)機(jī)很重要。主窗口第一次被創(chuàng)建時(shí)會(huì)傳送它WM-CREATE消息,這時(shí)是掛住中斷向量的最好時(shí)機(jī)。退出時(shí)需解掛向量,否則Windows可能崩潰。主窗口接收到WM-DE-STROY之后進(jìn)行解掛工作,是最適合的。解掛向量可先用INT35H,0204H功能將老的中斷向量保存,退出時(shí)用INT35H,0205H恢復(fù)。
五、編程實(shí)現(xiàn)
有了DPMI的支持,我們就可以很方便地處理數(shù)據(jù)采集、串行通信等工業(yè)過程中的實(shí)時(shí)事件。下面以Windows3.1平臺(tái)下中斷方式實(shí)現(xiàn)的串行通信為例,說明中斷程序的編制和實(shí)現(xiàn)。為便于參考,給出了詳細(xì)的代碼。開發(fā)平臺(tái)BC3.1/BC4.5,其本身支持0.9版的DPMI,無需運(yùn)行其它支持DPMI的軟件。編程語(yǔ)言C,可與C++混合編譯。
初始化COM1,9600波特率,每字符8bits,1個(gè)停止位,中斷接收,查詢發(fā)送。
//windows asy communication
//by Li Xiuming
//last modified on June 25,1996
#include〈windows.h〉
#include〈dos.h〉
void interrupt far DataReceive();
void interrupt far (*old-vector)();
unsigned char datacom-r[1024],datacom-s[1024];
int inflag=0;
unsigned int s8259;
int InitCom1()
{ //串口1初使化
s8259=inportb(0x21); //讀入8259當(dāng)前狀態(tài)并保存
outportb(0x21,s82590xe8); //初始化8259,允許0x0c號(hào)中斷
outportb(0x3fb,0x83);
outportb(0x3f8,0x0c);
outportb(0x3f9,0x00);
outportb(0x3fb,0x03);
outportb(0x3fc,0x08); //允許中斷信號(hào)送到8259A,以便能中斷
outportb(0x3f9,0x01); //0x01,中斷允許
return 1;
}
void interrupt far DataReceive()
{ //中斷接收子程序
static int i=0; //靜態(tài)局部變量
char rechar=0; //每中斷一次,i自動(dòng)加1
rechar=inportb(0x3f8); //從數(shù)據(jù)口讀出發(fā)送過來的數(shù)據(jù)
if(inflag==0)
{
if(rechar!=?s? i==0) //幀起始
{
i=0;
goto ll;
}
datacom-r[i++]=rechar; //存入datacom-r[](通信緩沖區(qū))
if(rechar==?e?) //幀結(jié)束
{
inflag=1;
i=0;
}
}
ll:outportb(0x20,0x20); //回送中斷結(jié)束標(biāo)志
}
//調(diào)用DPMI
//保存舊的0CH號(hào)保護(hù)模式中斷向量
//設(shè)置新的保護(hù)模式中斷服務(wù)例程
void InitCom(void)
{
asm{
cli
mov ax,204h
mov bl,0ch
int 31h
sti
}
old-vector=MK-FP(-CX,-DX);//保存
asm{ cli //設(shè)置新的0x0c中斷服務(wù)例程
mov ax,205h
mov bl,0ch
mov cx,seg datareceive
mov dx,offset datareceive
int 31h
sti
}
InitCom1();
}
//恢復(fù)8259狀態(tài)
//恢復(fù)0CH保護(hù)模式向量
void RestoreComm(void)
{
outportb(0x21,s8259);
asm{
cli
mov ax,205h
mov bl,0ch
mov cx,seg old-vector
mov dx,offset old-vector
int 31h
sti
}
}
在窗口第一次被創(chuàng)建時(shí)會(huì)傳送它WM-CREATE消息,這時(shí)調(diào)用InitCom()即可。在主窗口關(guān)閉時(shí),即主窗口中收到WM-DESTROY消息時(shí),調(diào)用RestoreComm()恢復(fù)原來的狀態(tài)。
這樣在對(duì)串口初始化,設(shè)置中斷服務(wù)例程后,通信事件發(fā)生時(shí),會(huì)立即跳入中斷子程序中執(zhí)行,越過系統(tǒng)的消息隊(duì)列,達(dá)到實(shí)時(shí)處理通信事件的目的。而數(shù)據(jù)處理模塊可通過全局標(biāo)志flag訪問全局的數(shù)據(jù)通信緩沖區(qū)獲取實(shí)時(shí)數(shù)據(jù)。這種實(shí)現(xiàn)方式與基于消息機(jī)制的Windows通信API實(shí)現(xiàn)相比具有實(shí)時(shí)性強(qiáng)的特點(diǎn),因?yàn)樗^Windows系統(tǒng)的兩極消息機(jī)制。
上述程序已在實(shí)際系統(tǒng)中得到應(yīng)用。在Windows 3.1支持下,同時(shí)運(yùn)行三個(gè)Windows任務(wù):服務(wù)器SERVER(內(nèi)有實(shí)時(shí)串行通信,多個(gè)網(wǎng)絡(luò)數(shù)據(jù)子服務(wù)),客戶CLIENT,FOXPRO數(shù)據(jù)庫(kù)系統(tǒng)。整個(gè)系統(tǒng)運(yùn)行良好。切換到WIN95平臺(tái)下(支持0.9版DPMI),系統(tǒng)也運(yùn)行良好。
參考文獻(xiàn)
1 張?jiān)シ?、曹建文譯.【澳】Barry Kauler著.Windows匯編語(yǔ)言及系統(tǒng)程序設(shè)計(jì).北京大學(xué)出版社,1995
2 趙人任等譯.【美】Mike Klein者.Windows程序員使用指南(一).北京:清華出版社,1995
3 劉林、陳紅編譯.80386硬件與接口技術(shù).北京:北京希望電腦公司,1991
評(píng)論