通过这几天的学习和查资料终于对矢量中断有所了解,并实现了在飞凌OK6410的开发板利用按键控制LED灯,其功能为如下
KEY1 ----LED1亮
KEY2 ----LED2亮
KEY3 ----LED3亮
KEY4 ----LED4亮
KEY5 ----LED1 与 LED4亮
KRY6 ---全灭
此开发板上按键有六个,LED灯有4个,电路图如下
难点在于对按键所对应的矢量中断上,其电路图如下,
原来,此开发板上的中断不是64个,而是64组,VIC0控制器和VIC1控制器个控制32组中断,而每组中断又可以有多个中断源,每个中断源又可以通过EINTxPEND寄存器来查询,所以对于以上按键来说,按键1~4产证的中断对应VIC0的0组寄存器,以上由硬件直接完成,再通过EINT0PEND,来进一步查询是此组中断中的哪个中断源产生的中断。
这里为中断初始化的核心代码,其中断初始化代码如下
void irq_init()
{
//配置按键中断下降沿触发
EINT0CON0 = (0b010)|(0b010 << 4)|(0b010 << 8);
//使能所有中断
EINT0MASK = 0;
//在中断控制器中使能VIC0的第0组中断和第1组中断
VIC0ENABLE |= (0b1) | (0b1 <<1);
//设置每组中断产生时对应的程序
VIC0VECTADDR0 = (int)handle;
VIC0VECTADDR1 = (int)handle2;
__asm__(
//6410特有的选择矢量中断,默认非矢量中断
"mrc p15, 0, r0, c1, c0, 0\n"
"orr r0, r0, #(1<<24)\n"
"mcr p15, 0, r0, c1, c0, 0\n"
//在CPSR寄存器中打开中断
"mrs r0, cpsr\n"
"bic r0, r0, #0x80\n"
"msr cpsr_c, r0\n"
:
:
);
}
处理中断源的代码如下
void handle()
{
//1.保护环境
__asm__(
"sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
//2.中断处理
switch(EINT0PEND)
{
case 1: led_on1(); break;
case 2: led_on2(); break;
case 4: led_on3(); break;
case 8: led_on4(); break;
default: break;
}
//3.清除中断
EINT0PEND = ~0x0;// 1清楚中断
VIC0ADDRESS = 0;
//4.恢复环境
__asm__(
"ldmfd sp!, {r0-r12, pc}^\n"
:
:
);
}
void handle2()
{
//1.保护环境
__asm__(
"sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
//2.中断处理
switch(EINT0PEND)
{
case 0x10: led_on5(); break;
case 0x20: led_off(); break;
default: break;
}
//3.清除中断
EINT0PEND = ~0x0;// 1清楚中断
VIC0ADDRESS = 0;
//4.恢复环境
__asm__(
"ldmfd sp!, {r0-r12, pc}^\n"
:
:
);
}