中断(按键)
1.中断概念
CPU在工作的过程中,经常需要与外设进行交互,交互的方式包括”轮询方式”,”中断方式”。
1.1 轮询方式
CPU不断地查询设备的状态。该方式实现比较简单,但CPU利用率很低,不适合多任务的系统。
1.2 中断方式
CPU在告知硬件开始一项工作后,就去做别的事去了,当硬件完成了该项工作后,向CPU发送一个信号,告知CPU它已经完成了这项工作。
2.中断生命周期
中断源(中断信号的产生)——中断控制器(中断信号过滤)——CPU(中断信号的处理)
中断源的作用是负责产生中断信号(6410支持64个中断源)
中断过滤:
中断信号处理:(6410向量方式)
- 当中断产生时CPU直接跳转到用户设置好的中断处理程序处
- 保护环境
- 设备的中断处理
- 恢复环境
3.中断编程
3.1 原理图
3.2 按键初始化
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #define GPNCON (volatile unsigned long*)0x7f008830 2 3 void button_init() 4 { 5 *(GPNCON) = 0B10; 6 }
3.3 初始化中断处理器
3.3.1 控制器的初始化
(使能中断、取消屏蔽外部中断、配置按键下降沿触发)
上升沿、下降沿触发配置(EINT0CON0 )
外部中断屏蔽
使能中断
开启总中断
中断向量的设置
清除中断
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #define EXT_INT_0_CON (volatile unsigned long*)0x7f008900 2 3 #define EXT_INT_0_MASK (volatile unsigned long*)0x7f008920 4 5 #define VIC0INTENABLE (volatile unsigned long*)0x71200010 6 7 #define EINT0_VECTADDR (volatile unsigned long*)0x71200100 8 9 #define EXT_INT_0_PEND (volatile unsigned long*)0x7f008924 10 11 #define VIC0ADDRESS (volatile unsigned long*)0x71200f00 12 13 void key_handle() 14 { 15 __asm__( 16 17 "sub lr, lr, #4\n" 18 "stmfd sp!, {r0-r12, lr}\n" 19 : 20 : 21 ); 22 23 // led_on(); 24 led_rol(); 25 /* 清除中断 */ 26 *(EXT_INT_0_PEND) = ~0x0; 27 *(VIC0ADDRESS) = 0; 28 29 __asm__( 30 "ldmfd sp!, {r0-r12, pc}^ \n" 31 : 32 : 33 ); 34 35 } 36 37 void init_irq() 38 { 39 *(EXT_INT_0_CON) = 0B010; 40 *(EXT_INT_0_MASK) = 0; 41 *(VIC0INTENABLE) |= 0X01; 42 43 *(EINT0_VECTADDR) = (unsigned long)key_handle; 44 45 __asm__( 46 "mrc p15,0,r0,c1,c0,0\n" 47 "orr r0,r0,#(1<<24)\n" 48 "mcr p15,0,r0,c1,c0,0\n" 49 50 "mrs r0,cpsr\n" 51 "bic r0, r0, #0x80\n" 52 "msr cpsr_c, r0\n" 53 : 54 : 55 ); 56 }
3.3.2 栈的初始化
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 init_stack: 2 msr cpsr_c, #0xd2 3 ldr sp, =0x53000000 //初始化r13_irq 4 msr cpsr_c, #0xd3 5 ldr sp, =0x54000000 //初始化R13_svc 6 mov pc ,lr