中断时中断寄存器的处理流程
扫描二维码
随时随地手机看文章
a.外部子中断
外部子中断的屏蔽位主要有两个寄存器(即屏蔽寄存器),EINTMASK和INTMSK,所以要产生中断,必须将这两个寄存器中对应的屏蔽位中断使能即可。这两个寄存器一般只在初始化的时候使用。
中断暂存寄存器,EINTPEND和SRCPND,中断产生后将会使这两个寄存器对应的位置1,所以中断服务函数必须将这两个寄存器中的对应的中断标志位清除(写1清除),否则会一直产生中断。注意:需要先清除EINTPEND,然后在清除SRCPND的中断标志位。这两个寄存器一般只在中断产生后中断标志的清除,用于中断服务函数中。
INTPND是中断最高优先级寄存器,也需要在中断服务函数中进行清除。
INTMOD是设置中断是FIQ还是IRQ,默认值为0x00000000,即默认值是IRQ。
PRIORITY是中断以何种优先级进行选择。
此外,外部中断是的设置还涉及到ARM的引脚设置,像GPxCON(引脚设置寄存器),EXTINT0-EXTINT2:分别设置EINT0—EINT7、EINT8—EINT15、EINT16—EINT23的触发方式(高电平触发、低电平触发、下降沿触发、上升沿触发)。EINTFLT0-EINTFLT3:控制滤波时钟和滤波宽度。
初始化处理步骤:
1)引脚的配置,GPxCON、EXTINT0、EXTINT1、EXTINT2的配置。
2)清除对应的中断屏蔽位,EINTMASK和INTMSK的设置。
3)将中断函数安装在软中断向量表中。
外部中断后的处理:
1)用户中断程序
2)中断暂存寄存器的处理,EINTPEND和SRCPND。注意先清除EINTPEND。
3)最高优先级的寄存器(INTPND)的清除。
b.外部中断
外部中断主要是EINT0~EINT3,相对于外部子中断的处理没有寄存器EINTPEND和EINTMASK,即子中断暂存寄存器和子中断屏蔽寄存器。如上图所示。
c.内部子中断
内部子中断和外部子中断主要是不用配置外部引脚,但是需要对其对应的模块寄存器进行设置,以及将EINTMASK和EINTPEND换成SUBSRCPND和INTSUBMSK即可。像UARTx中断中的子中断等。
d.内部中断
内部中断相对于外部子中断主要是没有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下降沿触发 10x Rising edge triggered上升沿触发 11x Both edge triggered双沿触发 */ // 设置K1,K2,K3,K4,K5按键中断触发方式为上升沿触发 rEXTINT1 = (3<<0) | (3<<12) | (3<<20) | (3<<24) | (3<<28); rEXTINT2 = (3<<12);// 设置K6按键中断触发方式为上升沿触 // 打开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; }