S5PV210有4个向量中断控制器(VIC),每个向量中断控制器包含32个中断源。

当某个中断源产生中断时,CPU会自动的将VICxVECTADDRy(x=0,1,2,3,y=0-31)寄存器的值赋给VICxADDRESS(x=0,1,2,3),因此我们可以把我们的中断处理函数的地址赋给VICxVECTADDRy寄存器,

比如我们有个函数

void key_handle()
{    
……
}

我们把key_handle 函数的值赋给VIC0VECTADDR0(外部中断0)

VIC0VECTADDR0 =key_handle;

当外部中断0触发中断时,CPU会自动的将VIC0VECTADDR0的值赋给VIC0ADDRESS,并跳转到这个地址去执行,即执行函数key_handle。

代码如下:

start.S

[cpp] view plaincopy
  1. .global _start                  /* 声明一个全局的标号 */
  2. .global key_isr
  3. _start:
  4. /* 设置栈,以调用c函数 */
  5. ldr sp, =0x40000000
  6. /* 开总中断 */
  7. mrs r0, cpsr
  8. bic r0, r0, #0x00000080     /* 清楚第7位,IRQ中断禁止位,写0使能IRQ */
  9. msr cpsr, r0
  10. bl main                     /* 跳转到C函数去执行 */
  11. halt:
  12. b halt
  13. key_isr:
  14. /* 计算返回地址:PC的值等于当前执行的地址+8,当CPU正要执行某条指令时(还未执行),被中断,
  15. ** 这是这条刚要执行的指令的地址刚好=PC-4 */
  16. sub lr, lr, #4
  17. stmfd sp!, {r0-r12, lr}     /* 保护现场 */
  18. bl key_handle
  19. /* 恢复现场 */
  20. ldmfd sp!, {r0-r12, pc}^    /* ^表示把spsr恢复到cpsr */

key.c

[cpp] view plaincopy
  1. #define GPC0CON             *((volatile unsigned int *)0xE0200060)
  2. #define GPC0DAT             *((volatile unsigned int *)0xE0200064)
  3. #define GPH0CON             *((volatile unsigned int *)0xE0200C00)
  4. #define GPH0DAT             *((volatile unsigned int *)0xE0200C04)
  5. #define EXT_INT_0_CON       *((volatile unsigned int *)0xE0200E00)
  6. #define EXT_INT_0_MASK      *((volatile unsigned int *)0xE0200F00)
  7. #define VIC0INTSELECT       *((volatile unsigned int *)0xF200000C)
  8. #define VIC0INTENABLE       *((volatile unsigned int *)0xF2000010)
  9. #define VIC0VECTADDR0       *((volatile unsigned int *)0xF2000100)
  10. #define VIC0VECTADDR1       *((volatile unsigned int *)0xF2000104)
  11. #define VIC0ADDRESS         *((volatile unsigned int *)0xF2000F00)
  12. #define EXT_INT_0_PEND      *((volatile unsigned int *)0xE0200F40)
  13. extern void key_isr(void);
  14. void key_handle()
  15. {
  16. volatile unsigned char key_code = EXT_INT_0_PEND & 0x3;
  17. VIC0ADDRESS = 0;        /* 清中断向量寄存器 */
  18. EXT_INT_0_PEND |= 3;    /* 清中断挂起寄存器 */
  19. if (key_code == 1)      /* key1 */
  20. GPC0DAT ^= 1 << 3;    /* toggle LED1 */
  21. else if (key_code == 2) /* key2 */
  22. GPC0DAT ^= 1 << 4;    /* toggle LED2 */
  23. }
  24. int main()
  25. {
  26. GPC0CON &= ~(0xFF << 12);
  27. GPC0CON |= 0x11 << 12;                    /* 配置GPC0_3和GPC0_4为输出:LED1和LED2 */
  28. GPH0CON |= 0xFF << 0;                 /* 配置GPH0_0和GPH0_1为外部中断:key1和key2 */
  29. EXT_INT_0_CON &= ~(0xFF << 0);
  30. EXT_INT_0_CON |= 2 | (2 << 4);            /* 配置EXT_INT[0]和EXT_INT[1]为下降沿触发 */
  31. EXT_INT_0_MASK &= ~3;                   /* 取消屏蔽外部中断EXT_INT[0]和EXT_INT[1] */
  32. VIC0INTSELECT &= ~3;                    /* 选择外部中断EXT_INT[0]和外部中断EXT_INT[1]为IRQ类型的中断 */
  33. VIC0INTENABLE |= 3;                     /* 使能外部中断EXT_INT[0]和EXT_INT[1] */
  34. VIC0VECTADDR0 = (int)key_isr;           /* 当EXT_INT[0]触发中断,即用户按下key1时,
  35. CPU就会自动的将VIC0VECTADDR0的值赋给VIC0ADDRESS并跳转到这个地址去执 */
  36. VIC0VECTADDR1 = (int)key_isr;
  37. while (1);
  38. return 0;
  39. }

Makefile

[cpp] view plaincopy
  1. key.bin: start.o key.o
  2. arm-linux-ld -Ttext 0x20000000 -o key.elf $^
  3. arm-linux-objcopy -O binary key.elf $@
  4. arm-linux-objdump -D key.elf > key.dis
  5. key.o : key.c
  6. arm-linux-gcc -c $< -o $@
  7. start.o : start.S
  8. arm-linux-gcc -c $< -o $@
  9. clean:
  10. rm *.o *.elf *.bin *.dis

将程序下载到内存运行

按下key1,LED1点亮,再次按下key1,LED1熄灭

按下key2,LED2点亮,再次按下key2,LED2熄灭

TQ210裸机编程(4)——按键(中断法)相关推荐

  1. TQ210裸机编程(3)——按键(查询法)

    首先查看TQ210的底板原理图 这次编程只操作KEY1和KEY2,在TQ210核心板原理图中搜索XEINT0 可以看出KEY1和KEY2分别接在S5PV210的GPH0_0和GPH0_1引脚. 这次编 ...

  2. 2440裸机编程之四 外部中断

    2440有60个中断源(有的中断源还有几个子中断源),中断原理如下图: 中断源使中断源请求寄存器(SRCPND)的相应位置一,中断模式寄存器(INTMOD)选择是IRQ还是FIQ模式,如果是IRQ,在 ...

  3. TQ210裸机编程(2)——LED流水灯

    两个文件start.S和led.c start.S .global _start                @声明一个全局的标号 _start:     bl main               ...

  4. 从ARM裸机看驱动之按键中断方式控制LED(一)

    硬件环境:Samsung Cortex-A9 Exynos4412 BSP + JTAG ARM 仿真器 软件环境:Eclipse ================================== ...

  5. 从ARM裸机看驱动之按键中断方式控制LED(二)

    硬件环境:Samsung Cortex-A9 Exynos4412 BSP 软件环境:Linux3.14 =============================================== ...

  6. S5PV210(TQ210)裸机编程

    本文更多的是教会大家如何学习. 4.1    汇编学习 4.1.1 基础知识     4.1.2 ARM模拟器 4.2    S5PV210启动流程 4.3    点亮一个LED 4.4    串口 ...

  7. MCU裸机编程的状态机框架--第一部分

    MCU裸机编程的状态机框架--第一部分 1 状态机的概念 1.1 状态机的要素 1.2 状态迁移表 1.3 状态机思路实现一个时钟程序 1.4 状态机应用的注意事项 1.5 更复杂的状态机 2 单片机 ...

  8. c语言 执行free函数程序被卡住,FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法...

    FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法 时间:2019-08-10 14:39:47  来源:  作者:  所属栏目:其他服务端 这里将告诉您FreeRT ...

  9. BSP板机支持包、linux启动分析、ARM裸机编程

    文章目录 一.BSP 二.驱动 驱动的基本要素 三.启动分析 1.uboot 2.uboot的作用 3.uboot相关命令 关键的内容: 1)bootargs,启动参数 2)启动命令 3)修改启动延时 ...

最新文章

  1. 嗨:VSCode和IDEA都请安装上这个神奇的插件
  2. webfocus在移动终端上的应用DEMO
  3. jQuery实战读书笔记(第五章)
  4. 警告:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA(亲测)
  5. 制作模块-制作模块压缩包
  6. ubuntu优化服务器网络连接数,ubuntu下解决高并发socket最大连接数限制,tcp默认1024个连接...
  7. AJAX 弹出窗消息类
  8. 俞敏洪最新干货演讲:在动荡的时代做不动荡的自己
  9. mysql链接丢失_mysql 连接丢失错误解决(转载)
  10. php分享二十:mysql优化
  11. 【计算机组成原理】课本总览
  12. python如何叉乘_向量点乘与向量叉乘
  13. 路由器温度测试软件,教你增强小米路由WEB管理(一)——添加CPU温度显示
  14. 零基础入行IC,选模拟版图还是数字后端?
  15. 苹果马桶iPoo,果粉还hold住吗
  16. 测试用例设计——错误猜测法
  17. 入职阿里巴巴的正确姿势
  18. django之csrf_exempt解决跨域请求的问题
  19. ThinkPad 插电时电源指示灯不亮
  20. 葡聚糖-叶酸;Dextran-FA;Dextran-Folicacid 结构式;科研试剂简介

热门文章

  1. 【C 语言】字符串模型 ( 字符串翻转模型 | 抽象成业务函数 | 形参返回值 | 函数返回值 | 函数形参处理 | 形参指针判空 )
  2. 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 )
  3. 【Android 应用开发】Activity 返回堆栈管理 ( 阶段总结 | 任务栈管理 | 返回堆栈 | 清除返回堆栈 | 亲和性 | 启动模式补充 | standard | singleTop )
  4. 【iOS 开发】iOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)
  5. 利用Nginx轻松实现Ajax的跨域请求(前后端分离开发调试必备神技)
  6. K-means算法应用:压缩图片
  7. centos ntfs-3g 安装和使用
  8. 【ASP.NET MVC 学习笔记】- 16 Model Binding(模型绑定)
  9. 需求分析读书笔记(一)
  10. Android 体系结构和应用程序组成