s5pv210中断体系
2015-12-29 23:00
399 查看
之前按键使用的是轮询法来做的按键检测的,但是这样太浪费CPU了,所以中断是必须的。
按键的原理图是这样的:
可以从原理图中看出中断是EINT16 -EINT27,
首先得把这些部分GPIO配置和为中断模式
@1:GPH2CON及GPH3CON 示例中断16的配置,首先配置为1111为中断模式
@2:EXT_INT_2_CON 外部中断控制
配置触发模式,我们可以配置为下降沿触发。
@3:使能中断
EXT_INT_2_MASK
@4:中断发生标志位
EXT_INT_2_PEND
以上这部分是关于GPIO的这部分的。下面是关于中断向量控制器的。
@1:CPSR使能bit7 则使能IRQ中断,使能bit6则使能FIQ中断。具体部分可以参考http://www.docin.com/p-961251144.html的文章。
@2:S5PV210 is composed of four Vectored Interrupt Controller (VIC), ARM PrimeCell,PL192 and four TrustZone Interrupt Controller (TZIC), SP890 就是说有4个中断向量控制器以及4个TZIC的控制器我们需要关心的是VIC控制器。
VIC0 - VIC3 每一个中断控制器控制32个中断号,分别是0-31,32-63,64-95,96-127。
我们仍然是以中断16为示例:
VIC0,所以这个中断应该是位于所有为0的标号控制着
@3 VIC0INTSELECT用来选择中断的类型
@4:VIC0INTENABLE 中断使能
@5:中断服务地址:
VIC0VECTADDR16 中存放中断服务函数的地址。
@6:有效的中断服务函数地址,例如中断16来到时,硬件会将VIC0VECTADDR16存放的地址放到VIC0ADDRESS中
VIC0ADDRESS
以下是webee210自带的裸板驱动:
start.s
这个关于210的中断体系以及调用过程并没有具体的介绍,可以参考http://www.docin.com/p-961251144.html的文章。
按键的原理图是这样的:
可以从原理图中看出中断是EINT16 -EINT27,
首先得把这些部分GPIO配置和为中断模式
@1:GPH2CON及GPH3CON 示例中断16的配置,首先配置为1111为中断模式
@2:EXT_INT_2_CON 外部中断控制
配置触发模式,我们可以配置为下降沿触发。
@3:使能中断
EXT_INT_2_MASK
@4:中断发生标志位
EXT_INT_2_PEND
以上这部分是关于GPIO的这部分的。下面是关于中断向量控制器的。
@1:CPSR使能bit7 则使能IRQ中断,使能bit6则使能FIQ中断。具体部分可以参考http://www.docin.com/p-961251144.html的文章。
@2:S5PV210 is composed of four Vectored Interrupt Controller (VIC), ARM PrimeCell,PL192 and four TrustZone Interrupt Controller (TZIC), SP890 就是说有4个中断向量控制器以及4个TZIC的控制器我们需要关心的是VIC控制器。
VIC0 - VIC3 每一个中断控制器控制32个中断号,分别是0-31,32-63,64-95,96-127。
我们仍然是以中断16为示例:
VIC0,所以这个中断应该是位于所有为0的标号控制着
@3 VIC0INTSELECT用来选择中断的类型
@4:VIC0INTENABLE 中断使能
@5:中断服务地址:
VIC0VECTADDR16 中存放中断服务函数的地址。
@6:有效的中断服务函数地址,例如中断16来到时,硬件会将VIC0VECTADDR16存放的地址放到VIC0ADDRESS中
VIC0ADDRESS
以下是webee210自带的裸板驱动:
start.s
.global _start .global IRQ_handle _start: ldr sp, =0x40000000 @设置栈,以便调用c函数 mov r0, #0x53 @进入SVC模式,开中断(把I位设为1) msr CPSR_cxsf, r0 bl main @调用main函数 IRQ_handle: ldr sp, =0xD0037F80 sub lr, lr, #4 @计算返回地址 stmfd sp!, {r0-r12, lr} @保存现场 bl irq_handler @跳转到中断处理函数 ldmfd sp!, {r0-r12, pc}^ @恢复现场main.c
#include "irq.h" #include "led.h" /* Key pins */ #define GPH2CON (*(volatile unsigned int *)0xE0200C40) #define GPH2DAT (*(volatile unsigned int *)0xE0200C44) unsigned int flag = 0; /* 延时函数 */ void delay(int count) { while (count--) ; } /* 真正的中断服务程序 */ void isr(void) { VIC0ADDRESS = 0; //清空中断向量地址 EXT_INT_2_PEND = 0xff; //清除中断标志 uart0_sendbyte('I'); uart0_sendbyte('R'); uart0_sendbyte('Q'); flag = 1; //如果有中断发生,则将flag置为1 } /* 功能:设置KEY引脚为外部中断模式 * 设置LED引脚为输出模式 */ void led_key_init(void) { /* Key pins */ GPH2CON = 0xf; //把GPH2_0设为外部中断16模式 /* LED pins */ GPJ2CON &= ~(0xffff); //把GPJ2_0~3设为输出 GPJ2CON |= 0x1111; } /* * 功能:打印 Webee210 interrupt test!! ^_^ */ void print_info() { uart0_sendbyte('W'); uart0_sendbyte('e'); uart0_sendbyte('b'); uart0_sendbyte('e'); uart0_sendbyte('e'); uart0_sendbyte('2'); uart0_sendbyte('1'); uart0_sendbyte('0'); uart0_sendbyte(' '); uart0_sendbyte('i'); uart0_sendbyte('n'); uart0_sendbyte('t'); uart0_sendbyte('e'); uart0_sendbyte('r'); uart0_sendbyte('r'); uart0_sendbyte('u'); uart0_sendbyte('p'); uart0_sendbyte('t'); uart0_sendbyte(' '); uart0_sendbyte('t'); uart0_sendbyte('e'); uart0_sendbyte('s'); uart0_sendbyte('t'); uart0_sendbyte('!'); uart0_sendbyte('!'); uart0_sendbyte(' '); uart0_sendbyte('^'); uart0_sendbyte('_'); uart0_sendbyte('^'); uart0_sendbyte('\r'); uart0_sendbyte('\n'); } int main(void) { led_init(); //LED初始化 sys_clock_init(); //时钟初始化 uart_init(); //串口初始化 print_info(); //输出 Webee210 interrupt test!! ^_^ led_key_init(); //初始化LED和按键 ext_int_init(); //初始化中断 while (1) { if(flag == 1) //如果有进入中断,则LED会闪烁 { led_flash(); } } return 0; }irq.c
#include "irq.h" /* 通用中断处理函数 */ void irq_handler(void) { void (*isr_p)(void) = (void (*)(void))VIC0ADDRESS; //取出中断服务程序地址 (*isr_p)(); //跳转真正的中断服务程序函数去 uart0_sendbyte('\r'); uart0_sendbyte('\n'); } void ext_int_init(void) { pExceptionIRQ = (unsigned long)IRQ_handle; //设置中断跳转地址 VIC0INTENCLEAR = 0xffffffff; //禁止所有中断 VIC0INTSELECT &= ~(1<<16); //将外部中断16设为IRQ模式 VIC0ADDRESS = 0; //清除需要处理的中断的中断处理函数的地址 EXT_INT_2_CON &= ~(7<<0); //把外部中断16设为下降沿触发 EXT_INT_2_CON |= 1<<1; EXT_INT_2_MASK &= ~(1<<0); //清除外部中断16的屏蔽,使能中断 VIC0INTENABLE |= 1<<16; //使能中断控制器 VIC0VECTADDR16 = (unsigned int )isr; //设置中断服务程序地址 }
这个关于210的中断体系以及调用过程并没有具体的介绍,可以参考http://www.docin.com/p-961251144.html的文章。
相关文章推荐
- Day-8 晚上。
- jinja2 字符串替换
- 浅谈innoDB,MYISAM
- python - StringIO文本缓冲
- 在Linux环境下安装部署MySQL数据库系统实例
- MongoDB 驱动以及分布式集群读取优先级设置
- 打开族,加载族
- de4dot3.14更新文件打包下载
- 2016年最值得关注的16个网页设计趋势
- Java网络连接之HttpURLConnection与HttpClient 区别及联系
- centos 安装qrcode 二维码
- VB 生成的EXE怎么更换桌面图标
- Open Source Software
- SQL 标量函数-----日期函数 day() 、month()、year()
- Linux笔记 vim
- System.Diagnostics.Process 执行.EXE
- C++编程思想学习笔记---第14章 继承和组合
- 热烈祝贺中国芯终于走在世界的前列
- 【网络流】:poj1698,Alice's Chance
- 从汇编和底层的角度看c和类c语言