a.外部子中斷
外部子中斷的屏蔽位主要有兩個寄存器(即屏蔽寄存器),EINTMASK和INTMSK,所以要產(chǎn)生中斷,必須將這兩個寄存器中對應的屏蔽位中斷使能即可。這兩個寄存器一般只在初始化的時候使用。
中斷暫存寄存器,EINTPEND和SRCPND,中斷產(chǎn)生后將會使這兩個寄存器對應的位置1,所以中斷服務函數(shù)必須將這兩個寄存器中的對應的中斷標志位清除(寫1清除),否則會一直產(chǎn)生中斷。注意:需要先清除EINTPEND,然后在清除SRCPND的中斷標志位。這兩個寄存器一般只在中斷產(chǎn)生后中斷標志的清除,用于中斷服務函數(shù)中。
INTPND是中斷最高優(yōu)先級寄存器,也需要在中斷服務函數(shù)中進行清除。
INTMOD是設置中斷是FIQ還是IRQ,默認值為0x00000000,即默認值是IRQ。
PRIORITY是中斷以何種優(yōu)先級進行選擇。
此外,外部中斷是的設置還涉及到ARM的引腳設置,像GPxCON(引腳設置寄存器),EXTINT0-EXTINT2:分別設置EINT0—EINT7、EINT8—EINT15、EINT16—EINT23的觸發(fā)方式(高電平觸發(fā)、低電平觸發(fā)、下降沿觸發(fā)、上升沿觸發(fā))。EINTFLT0-EINTFLT3:控制濾波時鐘和濾波寬度。
初始化處理步驟:
1)引腳的配置,GPxCON、EXTINT0、EXTINT1、EXTINT2的配置。
2)清除對應的中斷屏蔽位,EINTMASK和INTMSK的設置。
3)將中斷函數(shù)安裝在軟中斷向量表中。
外部中斷后的處理:
1)用戶中斷程序
2)中斷暫存寄存器的處理,EINTPEND和SRCPND。注意先清除EINTPEND。
3)最高優(yōu)先級的寄存器(INTPND)的清除。
b.外部中斷
外部中斷主要是EINT0~EINT3,相對于外部子中斷的處理沒有寄存器EINTPEND和EINTMASK,即子中斷暫存寄存器和子中斷屏蔽寄存器。如上圖所示。
c.內(nèi)部子中斷
內(nèi)部子中斷和外部子中斷主要是不用配置外部引腳,但是需要對其對應的模塊寄存器進行設置,以及將EINTMASK和EINTPEND換成SUBSRCPND和INTSUBMSK即可。像UARTx中斷中的子中斷等。
d.內(nèi)部中斷
內(nèi)部中斷相對于外部子中斷主要是沒有SUBSRCPND和INTSUBMSK。像Timer0中斷。
事例:
//****************外部子中斷*****************
void __irq Led_Isr(void)
{
unsigned long irqOffSet;
send_str((unsigned char *)"EXINT is started!rn");
Led_off(0);dely(50);
Led_on(0);dely(50);
irqOffSet = rINTOFFSET;// 取得中斷號
rEINTPEND &= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);
rSRCPND &= (1< rINTPND = rINTPND;// 清除中斷結果 send_str((unsigned char *)"EXINT is end!rn"); } extern void EINT_Init(void) { // 設置K1,K2,K3,K4,K5,K6對應控制寄存器為中斷模式 rGPGCON = (2<<0) | (2<<6) | (2<<10) | (2<<12) | (2<<14) | (2<<22); /* 01x falling edge triggered下降沿觸發(fā) 10x Rising edge triggered上升沿觸發(fā) 11x Both edge triggered雙沿觸發(fā) */ // 設置K1,K2,K3,K4,K5按鍵中斷觸發(fā)方式為上升沿觸發(fā) rEXTINT1 = (3<<0) | (3<<12) | (3<<20) | (3<<24) | (3<<28); rEXTINT2 = (3<<12);// 設置K6按鍵中斷觸發(fā)方式為上升沿觸 // 打開KEY1~KEY6的屏蔽位 rINTMSK &= ~(1<<5); rEINTMASK &= ~((1<<8) | (1<<11) | (1<<13) | (1<<14) | (1<<15) | (1<<19)); pISR_EINT8_23 = (unsigned int)Led_Isr; } //****************定時器***************** void __irq Timer0_isr() { send_str((unsigned char *)"Timer0 interrupt is started!rn"); Led_on(0);Led_off(1);Led_off(2);Led_off(3); dely(350); Led_off(0);Led_on(1);Led_off(2);Led_off(3); dely(350); Led_off(0);Led_off(1);Led_on(2);Led_off(3); dely(350); Led_off(0);Led_off(1);Led_off(2);Led_on(3); dely(350); rSRCPND |= 1<<10; rINTPND |= 1<<10; send_str((unsigned char *)"Timer0 interrupt is end!rn"); } void Init_timer0() { rTCFG0 &= ~(0xff); rTCFG0 |= 99; rTCFG1 &= ~(0xf); rTCFG1 |= 0x02; rTCNTB0 =62500;//1s中斷一次 rTCON |= 1<<1; rTCON = 0x09; //使能定時器中斷 rINTMSK = ~(1<<10); pISR_TIMER0= (unsigned int)Timer0_isr; } void Init_PWM0() { rGPBCON &= ~(0x03); rGPBCON |= 1<<1; rTCFG0 &= ~(0xff); rTCFG0 |= 99; rTCFG1 &= ~(0xf); rTCFG1 |= 0x02; rTCNTB0 =162;//1s中斷一次 rTCMPB0 = rTCNTB0/2; rTCON |= 1<<1; rTCON = 0x0d; }