新聞中心

s3c2440外部中斷操作

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
要想正確地執(zhí)行2440的外部中斷,一般需要完成兩個(gè)部分內(nèi)容:中斷初始化和中斷處理函數(shù)。
在具體執(zhí)行中斷之前,要初始化好要用的中斷。2440的外部中斷引腳EINT與通用IO引腳F和G復(fù)用,要想使用中斷功能,就要把相應(yīng)的引腳配置成中斷模式,如我們想把端口F0設(shè)置成外部中斷,而其他引腳功能不變,則GPFCON=(GPFCON & ~0x3) | 0x2。配置完引腳后,還需要配置具體的中斷功能。我們要打開(kāi)某一中斷的屏蔽,這樣才能響應(yīng)該中斷,相對(duì)應(yīng)的寄存器為INTMSK;還要設(shè)置外部中斷的觸發(fā)方式,如低電平、高電平、上升沿、下降沿等,相對(duì)應(yīng)的寄存器為EXTINTn。另外由于EINT4到EINT7共用一個(gè)中斷向量,EINT8到EINT23也共用一個(gè)中斷向量,而INTMSK只負(fù)責(zé)總的中斷向量的屏蔽,要具體打開(kāi)某一具體的中斷屏蔽,還需要設(shè)置EINTMASK。上面介紹的是最基本的初始化,當(dāng)然還有一些其他的配置,如當(dāng)需要用到快速中斷時(shí),要使用INTMOD,當(dāng)需要配置中斷優(yōu)先級(jí)時(shí),要使用PRIORITY等。
中斷處理函數(shù)負(fù)責(zé)執(zhí)行具體的中斷指令,除此以外還需要把SRCPND和INTPND中的相應(yīng)的位清零(通過(guò)置1來(lái)清零),因?yàn)楫?dāng)中斷發(fā)生時(shí),2440會(huì)自動(dòng)把這兩個(gè)寄存器中相對(duì)應(yīng)的位置1,以表示某一中斷發(fā)生,如果不在中斷處理函數(shù)內(nèi)把它們清零,系統(tǒng)會(huì)一直執(zhí)行該中斷函數(shù)。另外還是由于前面介紹過(guò)的,有一些中斷是共用一個(gè)中斷向量的,而一個(gè)中斷向量只能有一個(gè)中斷執(zhí)行函數(shù),因此具體是哪個(gè)外部中斷,還需要EINTPEND來(lái)判斷,并同樣還要通過(guò)置1的方式把相應(yīng)的位清零。一般來(lái)說(shuō),使用__irq這個(gè)關(guān)鍵詞來(lái)定義中斷處理函數(shù),這樣系統(tǒng)會(huì)為我們自動(dòng)保存一些必要的變量,并能夠在中斷處理函數(shù)執(zhí)行完后正確地返回。還需要注意的是,中斷處理函數(shù)不能有返回值,也不能傳遞任何參數(shù)。
為了把這個(gè)中斷處理函數(shù)與在2440啟動(dòng)文件中定義的中斷向量表相對(duì)應(yīng)上,需要先定義中斷入口地址變量,該中斷入口地址必須與中斷向量表中的地址一致,然后把該中斷處理函數(shù)的首地址傳遞給該變量,即中斷入口地址。
下面就是一個(gè)外部中斷的實(shí)例。開(kāi)發(fā)板上一共有四個(gè)按鍵,分別連到了EINT0,EINT1,EINT2和EINT4,我們讓這四個(gè)按鍵分別控制連接在B5~B8引腳上的四個(gè)LED:按一下鍵則LED亮,再按一下則滅:

#define _ISR_STARTADDRESS 0x33ffff00

#define U32 unsigned int

#define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1(*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2(*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT4_7(*(unsigned *)(_ISR_STARTADDRESS+0x30))

#define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt request status
#define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
#define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status

#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

#define rGPFCON(*(volatile unsigned *)0x56000050)//Port F control

#define rEXTINT0(*(volatile unsigned *)0x56000088)//External interrupt control register 0
#define rEINTMASK(*(volatile unsigned *)0x560000a4)//External interrupt mask
#define rEINTPEND(*(volatile unsigned *)0x560000a8)//External interrupt pending

static void __irq Key1_ISR(void) //EINT1
{
int led;
rSRCPND = rSRCPND | (0x1<<1);
rINTPND = rINTPND | (0x1<<1);
led = rGPBDAT & (0x1<<5);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<5);
else
rGPBDAT = rGPBDAT & ~(0x1<<5);
}

static void __irq Key2_ISR(void) //EINT4
{
int led;
rSRCPND = rSRCPND | (0x1<<4);
rINTPND = rINTPND | (0x1<<4);
if(rEINTPEND&(1<<4))
{
rEINTPEND = rEINTPEND | (0x1<<4);
led = rGPBDAT & (0x1<<6);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<6);
else
rGPBDAT = rGPBDAT & ~(0x1<<6);
}
}

static void __irq Key3_ISR(void) //EINT2
{
int led;
rSRCPND = rSRCPND | (0x1<<2);
rINTPND = rINTPND | (0x1<<2);
led = rGPBDAT & (0x1<<7);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<7);
else
rGPBDAT = rGPBDAT & ~(0x1<<7);
}

void __irq Key4_ISR(void) //EINT0
{
int led;
rSRCPND = rSRCPND | 0x1;
rINTPND = rINTPND | 0x1;
led = rGPBDAT & (0x1<<8);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<8);
else
rGPBDAT = rGPBDAT & ~(0x1<<8);
}

void Main(void)
{
int light;

rGPBCON = 0x015550;
rGPBUP = 0x7ff;
rGPFCON = 0xaaaa;

rSRCPND = 0x17;
rINTMSK = ~0x17;
rINTPND =0x17;
rEINTPEND = (1<<4);
rEINTMASK = ~(1<<4);
rEXTINT0 = 0x20222;

light = 0x0;
rGPBDAT = ~light;

pISR_EINT0 = (U32)Key4_ISR;
pISR_EINT1 = (U32)Key1_ISR;
pISR_EINT2 = (U32)Key3_ISR;
pISR_EINT4_7 = (U32)Key2_ISR;

while(1)
;
}


關(guān)鍵詞: s3c2440外部中斷操

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉