下面介绍一个中断实例,该例子实现了S5PC100按键控制。当按下KEY1和KEY2时,会从终端上打印出相应的按键信息。其中KEY1对应的是EINT1中断源,KEY2对应的是EINT2中断源。
1.电路原理
电路原理图如图7-10所示。
2.编程流程
编程流程如图7-11所示。
3.程序编写
(1)相关寄存器定义如下。
#define VIC0ADDRESS __REG(0xE4000F00)
#define VIC1ADDRESS __REG(0xE4100F00)
#define VIC2ADDRESS __REG(0xE4200F00)
#define VIC0VECADDR1 __REG(0xE4000104)
#define VIC0VECADDR2 __REG(0xE4000108) //定义寄存器地址
typedef struct {
unsigned int VIC0IRQSTATUS;
unsigned int VIC0FIQSTATUS;
unsigned int VIC0RAWINTR;
unsigned int VIC0INTSELECT;
unsigned int VIC0INTENABLE;
}interrupt;
#define INTERRUPT (* (volatile interrupt *)0xE4000000 )
(2)向量中断控制器初始化及配置。
VIC0VECADDR1 = (unsigned int)int_key1; //将中断向量地址寄存器赋值
GPH0.GPH0CON =(GPH0.GPH0CON & (~(0xf<<4)))+(0x2<<4);
INTERRUPT.VIC0INTENABLE = INTERRUPT.VIC0INTENABLE | (1<<1);//使能EINT1源
VIC0VECADDR2 = (unsigned int)int_key2;//将中断向量地址寄存器赋值
GPH0.GPH0CON =(GPH0.GPH0CON & (~(0xf<<8)))+(0x2<<8);
INTERRUPT.VIC0INTENABLE = INTERRUPT.VIC0INTENABLE | (1<<2);//使能EINT2源
(3)IRQ跳转函数的实现。
void do_irq()
{
printf("in do_irq\n");
((void (*)(void))VIC0ADDRESS)();
}
(4)按键1处理函数的实现。
/*中断处理程序1*/
void int_key1()
{
printf("in int_key1\r\n");
VIC0ADDRESS = 0;//清除中断
}
(5)按键2处理函数的实现。
/*中断处理程序2*/
void int_key2()
{
printf("in int_key2\r\n");
VIC0ADDRESS = 0; //清除中断
}
4.实验过程及结果描述
(1)将程序编译后产生.bin可执行文件,然后使用uboot的dnw命令下载到0x20008000这个内存地址,使用go命令去执行,并观察结果。
(2)终端打印结果如图7-12所示。