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 中断控制器的特点:

扫描二维码关注公众号,回复: 1861754 查看本文章

分为四种向量中断控制器、支持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清中断的操作的话,那么就会一直进入到中断服务程序当中!

猜你喜欢

转载自blog.csdn.net/mce_19/article/details/53338872