天天看点

GEC210(S5PV210)裸机驱动之按键(外部)中断

主机平台:Linux CentOS 6.5

arm平台:粤嵌GEC210开发板(S5PV210)

上次写了裸机中断中通用的部分,这次讲下如何编写某个特定的中断

先看一下上次写的步骤:

(1--7步是通用的部分,有不明白的话看一下我上一篇文章,这里省略)

8.编写外设对应的中断服务程序(第8、9步是中断驱动的重点)

9.设置外设寄存器初始化外设(包括清除中断标志位,使能中断等操作)

10.根据外设查找中断源表获得其中断号

11.根据中断号设置对应的中断服务程序入口地址寄存器(VICxVECTADDRx)

12.根据中断号使能对应中断

如上面所写8、9步是重点,因此将其再细分

8.编写外设对应的中断服务程序(第8、9步是中断驱动的重点)

8.1.根据标志为判断发生了什么中断。(当多个中断共享一个中断号时通常需要做此判断)

8.2.根据发生的中断执行相应的任务

8.3.清除所发生中断的中断标志位

8.4.清除全部VICxADDR(置0)

8.5.重新使能全局IRQ中断(进入中断后,全局IRQ中断会被关闭)

9.设置外设寄存器初始化外设(包括清除中断标志位,使能中断等操作)

9.1.关闭外设寄存器的中断使能

9.2.清除外设中断标志位

9.3.初始化设置与外设相关的其它寄存器。例如I/O的功能选择(这个容易忘记),设置输入时钟频率等等。

9.4开启外设对应中断

好了,下面就开始讲今次的主题:按键中断,采用外部中断24(EINT24),中断号为16

按上面步骤,先把思路写出来

8.编写外设对应的中断服务程序

8.1.判断该次中断是否由EINT24产生。因为EINT24--31共享16这个中断号,需要通过EXT_INT_3_PEND[0]位的值来判断。

8.2.执行对应任务。在我的程序中,是让一个变量自增并将其通过led显示。

8.3.清除中断标志位(向EXT_INT_3_PEND[0]写1)

8.4.清除全部VICxADDR(置0)

8.5.重新使能全局IRQ中断(进入中断后,全局IRQ中断会被关闭)

9.设置外设寄存器初始化外设(包括清除中断标志位,使能中断等操作)

9.1.关闭EINT24中断使能(EXT_INT_3_MASK[0])

9.2.清除EINT24的中断标志位 (EXT_INT_3_PEND[0])

9.3

(1)将EINT24对应的IO引脚功能设置为EXT_INT[24](GPH3CON[3:0])

(2)设置中断的触发方式(EXT_INT_3_CON[2:0])

9.4.使能EINT24(EXT_INT_3_MASK[0])

10.根据外设查找中断源表获得其中断号,可知中断号为16

11.根据中断号设置对应的中断服务程序入口地址寄存器(VIC3VECTADDR0)

12.根据中断号使能对应中断(VIC3INTENABLE[0])

跟着贴代码:

unsigned long ttt=0x5;
void eint24_func()
{
	unsigned long temp;

	if((*(volatile unsigned long *)0xe0200f4c)|0x1) //8.1 判断是否EINT24产生的中断
	{
		//temp=led_dat;
		//temp^=0xf;
		ttt=ttt+1;
		led_dat=~ttt;
		clear_vicaddress();  //8.4 清除<span style="color:#FF0000;">全部</span>VICxADDR(置0)
		EXT_INT_3_PEND|=0x1; //8.3.清除中断标志位(向EXT_INT_3_PEND[0]写1)
		enable_global_IRQ(); //8.5.重新使能全局IRQ中断
	}
	
}

void eint24_init()
{
	
	unsigned long temp;
        EXT_INT_3_MASK|=1;   //9.1.关闭EINT24中断使能
        EXT_INT_3_PEND|=0x1; //9.2.清除EINT24的中断标志位 (EXT_INT_3_PEND[0])
        key_con = 0x000f;    //9.3(1)将EINT24对应的IO引脚功能设置为EXT_INT[24](GPH3CON[3:0])
        EXT_INT_3_CON =0x2;  //9.3(2)设置中断的触发方式(EXT_INT_3_CON[2:0])        
        EXT_INT_3_MASK&=~1;  //9.4使能EINT24(EXT_INT_3_MASK[0])
        
        set_int_vectaddr(16,eint24_func);  //<span style="font-size:14px;">11.根据中断号设置对应的中断服务程序入口地址寄存器</span> 
        interrupt_enable(16);   //<span style="font-size:14px;">12.根据中断号使能对应中断(VIC3INTENABLE[0])</span>
}

<p>
</p>