Cortex A9 按键中断(SPI)流程
示例: KEY2 中断控制点亮 LED2
【0】检测按键k2,按键k2按下一次,灯LED2闪一次。
【1】查看原理图,连接引脚和控制逻辑
(1)按键k2 连接在GPX1_1引脚
(2)控制逻辑
k2 按下 ---- K2闭合 ---- GPX1_1 低电压
k2 常态 ---- K2打开 ---- GPX1_1 高电压
【2】查看相应的芯片手册
【2-1】循环检测GPX1_1引脚输入的电平,为低电压时,按键按下
(1)配置GPX1_1引脚功能为输入,设置内部上拉下拉禁止。
GPX1.CON = GPX1.CON &(~(0xf<<4)) ;
(2)循环检测 :
1 while(1)
2 {
3 if(!(GPX1.DAT & (0x1<<1))) // 返回为真,按键按下
4 {
5 msdelay(10);
6 if(!(GPX1.DAT & (0x1<<1))) //二次检测,去抖
7 {
8 GPX2.DAT |= 0x1 << 7; //Turn on LED2
9 mydelay_ms(500);
10 GPX2.DAT &= ~(0x1<<7); //Turn off LED2
11 mydelay_ms(500);
12
13 while(!(GPX1.DAT & (0x1<<1)));
14 }
15 }
16 }
【2-2】中断方法检测按键
将K2按下时,GPX1_1引脚获得的电平,作为异常事件。使能异常处理,k2每按下一次,响应一次异常处理。SPI 传递流程如下示:
(1)外设一级 --- GPIO控制器
0-- 将GPX1_1引脚的上拉和下拉禁止
GPX1PUD[3:2]= 0b00;
1-- 将GPX1_1引脚功能设置为中断功能 WAKEUP_INT1[1] --- EXT_INT41[1]
GPX1CON[7:4] = 0xf
2-- EXT_INT41CON 配置触发电平
当前配置成下降沿触发:
EXT_INT41CON[6:4] = 0x2
3-- EXT_INT41_FLTCON0 配置中断引脚滤波
默认就是打开的,不需要配置
4--EXT_INT41_MASK 中断使能寄存器
使能INT41[1]
EXT_INT41_MASK[1] = 0b0
5--EXT_INT41_PEND 中断状态寄存器
当GPX1_1引脚接收到中断信号,中断发生,中断状态寄存器EXT_INT41_PEND 相应位会自动置1
注意:中断处理完成的时候,需要清除相应状态位。置1清0.
EXT_INT41_PEND[1] =0b1
(2)中断控制器
0--找到外设中断名称和GIC中断控制器对应的名称
查看芯片手册(本例:9.2表):
WAKEUP_INT1[1] --- EXT_INT41[1] --- INT[9] --- SPI[25]/ID[57]
1--使能cpu0的spi25/id57
ICDISER.ICDISER1 |= (0x1 << 25); //57/32 =1...25 取整数(那个寄存器) 和余数(哪位)
2--全局使能cpu0中断处理
CPU0.ICCICR |= 0x1;
3--优先级屏蔽寄存器,设置cpu0能处理所有的中断。
CPU0.ICCPMR = 0xFF;
4--GIC使能
ICDDCR =1;
5--设置SPI[25]/ID[57]由那个cpu处理,当前设置为cpu0的irq中断
ICDIPTR.ICDIPTR14 |= 0x01<<8; //SPI25 interrupts are sent to processor 0 //57/4 = 14..1 14号寄存器的[15:8]
(3)ARM内核(cpu)
1--四大步三小步 --- 硬件
1 .text
2 .global _start
3 _start:
4 b reset
5 ldr pc,_undefined_instruction
6 ldr pc,_software_interrupt
7 ldr pc,_prefetch_abort
8 ldr pc,_data_abort
9 ldr pc,_not_used
10 ldr pc,_irq
11 ldr pc,_fiq
12
13 _undefined_instruction: .word _undefined_instruction
14 _software_interrupt: .word _software_interrupt
15 _prefetch_abort: .word _prefetch_abort
16 _data_abort: .word _data_abort
17 _not_used: .word _not_used
18 _irq: .word irq_handler
19 _fiq: .word _fiq
20
21
22 reset:
23
24 ldr r0,=0x40008000
25 mcr p15,0,r0,c12,c0,0 @ Vector Base Address Register
26
27 mrs r0,cpsr
28 bic r0,r0,#0x1f
29 orr r0,r0,#0xd3
30 msr cpsr,r0 @ Enable svc mode of cpu
31
32 mov r0, #0xfffffff
33 mcr p15, 0, r0, c1, c0, 2 @ Defines access permissions for each coprocessor
34 @ Privileged and User mode access
35
36 /*
37 * Invalidate L1 I/D
38 */
39 mov r0, #0 @ set up for MCR
40 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
41 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
42
43
44 @Set the FPEXC EN bit to enable the FPU:
45 MOV r3, #0x40000000
46 fmxr FPEXC, r3
47
48 /*
49 * disable MMU stuff and caches
50 */
51 mrc p15, 0, r0, c1, c0, 0
52 bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
53 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
54 orr r0, r0, #0x00001000 @ set bit 12 (---I) Icache
55 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
56 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
57 mcr p15, 0, r0, c1, c0, 0
58
59 /* LED Test Code */
60
61 ldr r0, =0x114001E0
62 ldr r1, [r0]
63 bic r1, r1, #0xf0000
64 orr r1, r1, #0x10000
65 str r1, [r0]
66
67 ldr r0, =0x114001E8
68 ldr r1, [r0]
69 bic r1, r1, #0x300
70 str r1, [r0]
71
72 ldr r0, =0x114001E4
73 ldr r1, [r0]
74 orr r1, r1, #0x10
75 str r1, [r0]
76
77 init_stack:
78 ldr r0,stacktop /*get stack top pointer*/
79
80 /********svc mode stack********/
81 mov sp,r0
82 sub r0,#128*4 /*512 byte for irq mode of stack*/
83 /****irq mode stack**/
84 msr cpsr,#0xd2
85 mov sp,r0
86 sub r0,#128*4 /*512 byte for irq mode of stack*/
87 /***fiq mode stack***/
88 msr cpsr,#0xd1
89 mov sp,r0
90 sub r0,#0
91 /***abort mode stack***/
92 msr cpsr,#0xd7
93 mov sp,r0
94 sub r0,#0
95 /***undefine mode stack***/
96 msr cpsr,#0xdb
97 mov sp,r0
98 sub r0,#0
99 /*** sys mode and usr mode stack ***/
100 msr cpsr,#0x10
101 mov sp,r0 /*1024 byte for user mode of stack*/
102
103 b main
104
105 .align 4
106
107