S3C2440 測(cè)試程序(四) 外部中斷實(shí)驗(yàn)
TQ2440板上將4個(gè)按鍵K1~K4分別接在4個(gè)外部中斷口上:
K1 ---- EINT1(GPF1)
K2 ---- EINT4(GPF4)
K3 ---- EINT2(GPF2)
K4 ---- EINT0(GPF0)
K5 ---- EINT5(GPF5)外接單片機(jī)的I/O口
主程序里初始化:KeyPort_Init(); 之后while(1) ;
void KeyPort_Init(void)
{
rGPFCON = rGPFCON & ~((3<<0)|(3<<2)|(3<<4)|(3<<8)|(3<<10))
|((2<<0)|(2<<2)|(2<<4)|(2<<8)|(2<<10));
//將GPF的5個(gè)口設(shè)置為ENT0 ENT1 ENT2 ENT4 EINT5(10為外部中斷)
rEXTINT0 = rEXTINT0 & ~((7<<0)|(7<<4)|(7<<8)|(7<<16)|(7<<20))
|((6<<0)|(6<<4)|(6<<8)|(6<<16)|(6<<20));
//設(shè)置ENT0 ENT1 ENT2 ENT4 ENT5觸發(fā)條件為上升沿和下降沿觸發(fā):
//000 -- 低電平觸發(fā) 001 -- 高電平觸發(fā) 01x -- 下降沿觸發(fā)
//10x -- 上升沿觸發(fā) 11x --上升沿和下降沿都觸發(fā)
rEINTPEND |= ((1<<4)|(1<<5));
//寫1清rEINTPEND 的EINT4 EINT5位,無0-3位
rEINTMASK &= ~((1<<4)|(1<<5));
//enable EINT4 EINT5,無0-3
pISR_EINT0 = pISR_EINT1 = pISR_EINT2 = pISR_EINT4_7 = (U32)Key_ISR;
//將EINT0 EINT1 EINT2 EINT4_7的入口地址都等于中斷地址,這樣可以共用一個(gè)中斷函數(shù)
//缺點(diǎn)是要在終端函數(shù)中去判斷為哪個(gè)外部中斷響應(yīng)
rSRCPND = rSRCPND & ~((1<<0)|(1<<1)|(1<<2)|(1<<4))|((1<<0)|(1<<1)|(1<<2)|(1<<4));
rINTPND = rINTPND & ~((1<<0)|(1<<1)|(1<<2)|(1<<4))|((1<<0)|(1<<1)|(1<<2)|(1<<4));
//rSRCPND rINTPND 為中斷未決寄存器,中斷使能前寫1清除
rINTMSK &= ~((1<<0)|(1<<1)|(1<<2)|(1<<4));
//enable irq:0 -- available 1-- masked
//具體寄存器說明見下節(jié)
}
下面為中斷函數(shù):
該函數(shù)例程里跑起來有個(gè)很不爽的效果就是,按按鍵或抬起按鍵會(huì)出現(xiàn)多次中斷,是機(jī)械按鍵會(huì)有抖動(dòng)造成的,故特加了個(gè)EINT5用單片機(jī)輸出電平來測(cè)驗(yàn)。K1~K4我將源代碼加于改進(jìn),中斷照進(jìn),但不打印信息,實(shí)際運(yùn)用可以在這設(shè)個(gè)標(biāo)志位。最后打印出來的效果為:
K1發(fā)生中斷
K1已抬起
K2發(fā)生中斷
K2已抬起
K3發(fā)生中斷
K3已抬起
K4發(fā)生中斷
K4已抬起
static void __irq Key_ISR(void)
{
U32 r;
EnterCritical(&r); //保護(hù)臨界狀態(tài),暫不懂這個(gè)是什么意思
if((rGPFDAT&0x37) == 0x37)
gKeyPressFlag = 0; //no key press
else
gKeyPressFlag = 1; //key press
if(gKeyPressFlag) //下降沿觸發(fā)
{
gKeyReleaseFlag = 1;
if(rINTPND==0x01) //EINT0 -- K4為什么是判斷INTPND,見下節(jié)解釋
{
rSRCPND = 0x01;
rINTPND = 0x01; //clear pending bit
Led_Display(0x01);
if(gKeyLongPressFlag == 0)
{
gKeyLongPressFlag = 1;
Uart_Printf("K4發(fā)生中斷n");
}
}
if(rINTPND==0x02) //EINT1 -- K1
{
rSRCPND = 0x02;
rINTPND = 0x02;
Led_Display(0x02);
if(gKeyLongPressFlag == 0)
{
gKeyLongPressFlag = 1;
Uart_Printf("K1發(fā)生中斷n");
}
}
if(rINTPND==0x04) //EINT2 -- K3
{
rSRCPND = 0x04;
rINTPND = 0x04;
Led_Display(0x04);
if(gKeyLongPressFlag == 0)
{
gKeyLongPressFlag = 1;
Uart_Printf("K3發(fā)生中斷n");
}
}
if(rINTPND==0x10) //EINT4——7 --K2、K5
{
rSRCPND = 0x10;