ARM 中断--IRQ and FIQ配置--外部配置
中断分为外部中断和定时器中断;
中断源都是有一个触发条件,条件满足就会产生中断。不同的中断源触发条件不一样
ARM中中断分为两种:FIQ(fast interrupt request)快速中断请求,IRQ(interrupt requrest)一般的中断请求
为什么FIQ比IRQ的中断响应更快?
在ARM体系中,FIQ的优先级比IRQ高,FIQ优先级为3,IRQ优先级为4,FIQ和IRQ是中断的两种不同类型,FIQ比IRQ有更多的分组寄存器,在中断响应的时候,就不要入栈出栈寄存器。
S5PV210系统中的中断分层:
外部中断/定时器 -> 中断控制器 -> 内核
VECTORED INTERRUPT CONTROLLER 向量控制中断器 VIC
向量中断:每一个中断源都有自己的入口地址/地址寄存器
S5PV210 中断控制器的特点:
分为四种向量中断控制器、支持93种一般中断、有固定的优先级但是可以设置优先级、中断源可以设置为FIQ或者IRQ
1)设置外部中断先由管脚的属性开始设置,在GP管脚的属性设置中有EXT_INT【*】选项
例如: GPH2CON[2] 控制的0-3位全部置为1,1111=EXT_INT[16],第16号外部中断
2)设置外部中断的触发方式,根据EXT_INT[16]被哪一个寄存器所管,可以从手册查,EXT_INT_2_CON控制着外部中断16到23号,然后设置EXT_INT_2_CON就可以设置外部中断触发方式了(高电平、低电平、下降沿、上升沿、下降上升沿)。
3)设置外部中断屏蔽寄存器,EXT_INT_n_MASK,这个寄存器用来设置屏蔽或者不屏蔽外部中断的信号,16号外部中断由EXT_INT_2_MASK控制,设置该寄存器打开或者关闭,1关闭0打开,默认为关闭,此为保护措施
4)设置外部中断判断寄存器,用来判断外部中断是否已经发生,发生之后消除中断,查阅同上理,EXT_INT_2_PEND,可读可写寄存器,有中断产生寄存器自动置为1,那么在中断服务程序之后就要再次手动置1用来消除中断!
5)设置中断源选择寄存器,VICINTSELECT,选择中断源是FIQ还是IRQ,那么怎么知道我们控制的中断信号是属于VIC多少呢?可以查手册560页,位设置总共有32位,0为IRQ1为FIQ,每一位都代表着是一个中断源
6)设置VICIRQSTATUS,判断IRQ是否发生的寄存器,只读,0中断没有发生1中断已经发生
7)设置VICINTENABLE,中断使能寄存器,可读可写,1为使能中断,0为无效写入,因为初始化状态下所有中断都是关闭的
外部中断四个按键低电平触发控制四个LED
#include "int.h"
int flag=4;
void int_init( void);
void intc_setvectaddr(unsigned long intnum, void (*handler)(void));
void intc_clearvectaddr(void);
void intc_enable(unsigned long intnum);
void isr_key(void)
{
if((EXT_INT_3_PEND&0x1)==1)
GPJ2DAT ^= (1<<0); //toggle
if(((EXT_INT_3_PEND>>1)&0x1)==1)
GPJ2DAT ^= (1<<1); //toggle
if(((EXT_INT_3_PEND>>2)&0x1)==1)
GPJ2DAT ^= (1<<2); //toggle
if(((EXT_INT_3_PEND>>3)&0x1)==1)
GPJ2DAT ^= (1<<3); //toggle
intc_clearvectaddr();
EXT_INT_3_PEND |= 0XF<<0;
}
int main(void)
{
GPJ2CON &=~(0xffff);
GPJ2CON |= (0x1111);
int_init();
GPH3CON = (0XFFFF);
EXT_INT_3_CON &=~(0XFFF);//低电平触发
intc_setvectaddr(NUM_EINT16_31, isr_key);
EXT_INT_3_MASK &= ~(0xF<<0);//不屏蔽中断
intc_enable(NUM_EINT16_31);
while (1);
}
首先配置GPIOCON寄存器然后初始化然后设置外部触发模式为低电平触发,设置中断服务程序,不屏蔽中断(因为系统默认是屏蔽中断的)
initial state初始状态为1 那么就是屏蔽状态,如果要使用中断那么就要设定为0
之后就是初始化中断。
在中断服务函数当中可以根据PEND函数来判断是哪一个按键触发了中断,然后需要把四个VIC地址写零
之后再是把PEND写1置零。
值得注意的是系统判断中断有没有并不是看到底有没有触发,而是看 EXT_INT_n_PEND的位值判断,如果是 1 那么就是有中断没有就是没中断,如果在中断服务程序中屏蔽掉PEND函数的置1清中断的操作的话,那么就会一直进入到中断服务程序当中!
转载地址:http://www.eeworld.com.cn/mcu/2018/ic-news071640340.html