一、外部中断分组:
外部中断组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, 0\n" 4 "orr r0, r0, #(1 << 24)\n" 5 "mcr p15, 0, r0, c1, c0, 0\n" 6 //开RIQ总中断 7 "mrs r0, cpsr\n" 8 "bic r0, r0, #(1 << 7)\n" 9 "msr cpsr_c, r0\n" 10 : 11 : 12 );
7、编写中断服务程序
保护现场
中断程序
清除中断标志
EINT0PEND清除中断标志(写1清零)
VICxADDRESS清除向量地址
恢复现场
1 void IRQ_Handle_Exit(void) 2 { 3 //保护现场 4 __asm__( 5 "sub lr, lr, #4\n" 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