一、外部中断分组:
外部中断组0 GROUP0 GPN0--GPN15 GPL8--GPL14 GPM0--GPM4
外部中断组1 GROUP1 GPA0--GPA7 GPB0--GPB6
外部中断组2 GROUP2 GPC0--GPC7
外部中断组3 GROUP3 GPD0--GPD5
外部中断组4 GROUP4 GPF0--GPF14
外部中断组5 GROUP5 GPG0--GPG7
外部中断组6 GROUP6 GPH0--GPH9
外部中断组7 GROUP7 GPO0--GPO15
外部中断组8 GROUP8 GPP0--GPP14
外部中断组9 GROUP9 GPQ0--GPQ9
二、中断组的中断号:
NO 中断源 说明 GROUP
0 INT_EINT0 外部中断组0 bit[0-3] VIC0
1 INT_EINT1 外部中断组0 bit[4-11] VIC0
32 INT_EINT2 外部中断组0 bit[12-19] VIC1
33 INT_EINT3 外部中断组0 bit[20-27] VIC1
53 INT_EINT4 外部中断组1-9 VIC1
三、中断程序配置:
1、设置相应的GPIO口为外部中断模式;
所用到的寄存器:GPxCON
1 //清除GPN0 GPN1
2 GPNCON &=~(3 << 0);
3 GPNCON &=~(3 << 2);
4
5 //GPN0 GPN1设置为中断模式
6 GPNCON |= (1 << 1);
7 GPNCON |= (1 << 3);
2、配置外部中断相关的配置寄存器;
所用到的寄存器:EINT0CONx(配置中断触发方式)
EINT0MASK(失能中断屏蔽,使能中断)
PRIORITY(中断优先级配置)
1 //EINT0,1下降沿触发
2 EINT0CON0 &=~(7 << 0);
3 EINT0CON0 |= (2 << 0);
4
5 //失能中断屏蔽
6 EINT0MASK &=~(1 << 0);
7 EINT0MASK &=~(1 << 1);
3、使能中断源请求
所用到的寄存器:VICxINTENABLE
1 /使能中断源请求
2 VIC0INTENABLE |= (1 << 0);
4、配置向量地址
所用到的寄存器:VIC0VECTADDRx(把中断服务函数的地址写入向量地址寄存器)
1 //配置向量地址
2 VIC0VECTADDR0 = (int)IRQ_Handle_Exit;
5、允许向量中断(6410支持非向量中断和向量中断。210只支持向量中断不需要做此步骤)
所用到的寄存器:协处理器CP15的C1控制寄存器(置位bit24)
6、使能IRQ中断(开总中断)
所用到的寄存器:程序状态寄存器CPSR
1 __asm__(
2 //允许向量中断
3 'mrc p15, 0, r0, c1, c0, 0n'
4 'orr r0, r0, #(1 << 24)n'
5 'mcr p15, 0, r0, c1, c0, 0n'
6 //开RIQ总中断
7 'mrs r0, cpsrn'
8 'bic r0, r0, #(1 << 7)n'
9 'msr cpsr_c, r0n'
10 :
11 :
12 );
7、编写中断服务程序
保护现场
中断程序
清除中断标志
EINT0PEND清除中断标志(写1清零)
VICxADDRESS清除向量地址
恢复现场
1 void IRQ_Handle_Exit(void)
2 {
3 //保护现场
4 __asm__(
5 'sub lr, lr, #4n'
6 'stmfd sp!, {r0-r12, lr}n'
7 :
8 :
9 );
10
11 //服务程序
12 if(EINT0PEND & (1 << 0)) //EINT0
13 {
14 led_all_on();
15 }
16 else if(EINT0PEND & (1 << 1)) //EINT1
17 {
18 led_all_off();
19 }
20
21 //清除中断标志
22 EINT0PEND = 0xFFFFFFFF;
23 VIC0ADDRESS = 0x00000000;
24
25 //恢复现场
26 __asm__(
27 'ldmfd sp!, {r0-r12, pc}^n'
28 :
29 :
30 );
31 }
8、启动代码设置
设置IRQ堆栈
1 //start.S
2 init_stack:
3 //初始化IRQ SP
4 msr cpsr_c, #0xd2
5 ldr sp, =0x53000000
6
7 //初始化SVC SP
8 msr cpsr_c, #0xd3
9 ldr sp, =0x54000000
10 mov pc ,lr