×
单片机 > 单片机程序设计 > 详情

中断时中断寄存器的处理流程

发布时间:2020-05-30 发布时间:
|

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!\r\n");

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!\r\n");

}


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!\r\n");

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!\r\n");

}

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;

}




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会