6410按键中断编程

一、流程分析

外部中断控制寄存器(s3c6410x  359页)

  

  

1、EINTxCONy: 外部中断组x的第y个控制器。这个就是设置中断的触发方式。有5种触发方式。

  

2、EINTxFLTCONy:外部中断组x的第y个滤波功能控制器。S3C6410对于外部中断有滤波功能,这个就是用来设置滤波功能。有延迟滤波,有数字滤波。滤波,可以用来滤掉毛刺信号。在以前51做按键外部中断,按键是有抖动的,就需要一个去抖动的一个东西。但是有了这个滤波的话,直接设定滤波的时间,就可以滤掉这一段时间的毛刺了。就不用再加去抖动的程序了。

  

3、EINTxMASK:外部中断组x的屏蔽寄存器。用来使能中断的。当要使用某个中断的时候,就需要让这个中断使能,就需要在这个寄存器中的对应位写入0,来打开中断。默认为中断都是屏蔽的。

  

4、EINTxPEND:外部中断组x的中断挂起寄存器。这个寄存器就是用来保存中断的状态的。当对应的中断产生时,对应的位为1。当中断处理完毕后,需要往对应对写入1进行清除。

1.1设置引脚为中断模式

  初始化中断源,也就是设置中断源是什么,以及中断的触发方式(高电平,低电平,上边沿,下降沿,双边沿)

  

  #define GPNCON (volatile unsigned long*)0x7f008830

  void button_init()

  {

   *(GPNCON) = 0xaaa;

  }

1.2中断控制器

  初始化中断控制器,也就是使能对应的中断,让中断信号能够传递到CPU。在这里还需要设置中断优先级,中断滤波等与中断的相关设置

  这两个是中断控制器,分别管理各自的32个中断(6410数据手册410页)

  

  为了节约中断,不可能为每个外部管脚都分配一个中断号,所以就会把某几个外部中断给合并成一个中断号。例如,对于外部中断0-3,就合并成了一个中断号,INT_EINT0。当这4个中断有任意一个产生中断时,INT_EINT0会挂起,CPU就会知道产生了外部中断0-3中断,然后去执行中断处理,在中断服务程序中,为了知道具体是哪一个中断,还需要去查询寄存器以知道是哪一个中断产生。

  

  S3C6410中断处理有向量模式和非向量方式。因为要与之前的ARM系列兼容,所以保存了非向量方式。

1.3中断触发方式

  //配置按键中断下降沿出发

  *(EINT0CON0) = 0x222;

1.4取消中断屏蔽

  //打开外部中断(取消中断屏蔽)

  *(EINT0MASK) = 0;

1.5使能中断号

  //使能外部中断号

  *(VIC0INTENABLE) = 0x00000003;

1.6编写中断处理入口

  //将函数地址赋给中断处理程序

  *(VIC0VECTADDR0) = (int)key1_lsr;

  *(VIC0VECTADDR1) = (int)key2_lsr;

1.7开启向量中断

  

1.8打开总中断

  

1.9编写中断服务函数

  在中断函数前和中断函数末尾都有使用嵌入汇编。这段代码是固定的。目的是为了保存环境,将r0-r12,lr寄存器的值给压入栈中,然后执行完后,在将这些值返回给r0-r12,pc寄存器。这样r0-r12寄存器的内容就恢复了,同时pc得到返回地址,就返回到中断前的程序地址去了。

  这里有sub lr,lr,#4。将lr的值减去4。这个原因就要从ARM的流水线说起了。ARM采用流水线,取址,译码,执行。所以pc的值永远是当前执行指令的地址+8.

  中断跳转的时候,会将pc的值给lr,pc的值为当前执行程序地址+8,lr的值就是pc的值。而返回的地址应该是执行阶段的下一条地址,也就是当前执行程序地址+4,所以直接返回lr的值就不对了,应该返回lr-4的值。

  

  中断处理完后,需要将中断挂起位给清零。这里,很简单的将所有中断位都给清零。然后再将中断执行地址给清0。

  这个寄存器,当执行中断函数的时候,值是中断函数的入口地址。往这个寄存器写入任意的值,就清除这个中断了。所以最后需要将这个寄存器给清0。

  

  if((0x01 & GPNDAT) == 0)

     led_on(1);

  

  因为外部中断源INT_EINT0里面包含外部0~3四个外部中断,所以要通过相应I/O口寄存器数据判断是哪个中断被触发。

二、源代码如下:

 /*interrupt registes*/
#define EXT_INT_0_CON *((volatile unsigned int *)0x7f008900)
#define EXT_INT_0_MASK *((volatile unsigned int *)0x7f008920)
#define EXT_INT_0_PEND *((volatile unsigned int *)0x7f008924) #define VIC0INTENABLE *((volatile unsigned int *)0x71200010) #define EINT0_VECTADDR *((volatile unsigned int *)0x71200100)
#define EINT5_VECTADDR *((volatile unsigned int *)0x71200104) #define VIC0ADDRESS *((volatile unsigned int *)0x71200f00)
#define VIC1ADDRESS *((volatile unsigned int *)0x71300f00) #define GPNDAT *((volatile unsigned int *)0x7F008834)
void key1_handle()
{
__asm__( "sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
if((0x01 & GPNDAT) == )
led_on();
if((0x02 & GPNDAT) == )
led_on();
if((0x04 & GPNDAT) == )
led_on();
if((0x08 & GPNDAT) == )
led_on();
/* 清除中断 */
EXT_INT_0_PEND = ~0x0;
VIC0ADDRESS = ;
VIC1ADDRESS = ; __asm__(
"ldmfd sp!, {r0-r12, pc}^ \n"
:
:
); } void key6_handle()
{
__asm__( "sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
if((0x10 & GPNDAT) == )
led_on();
if((0x20 & GPNDAT) == )
led_off();
/* 清除中断 */
EXT_INT_0_PEND = ~0x0;
VIC0ADDRESS = ;
__asm__(
"ldmfd sp!, {r0-r12, pc}^ \n"
:
:
);
} void init_irq()
{
EXT_INT_0_CON = 0x222; /* 配置为下降沿触发 */ EXT_INT_0_MASK = ; /* 取消屏蔽外部中断 */ VIC0INTENABLE = 0x00000003; /* 使能外部中断*/ EINT0_VECTADDR = (int)key1_handle; /* 用户按下key时,CPU就会自动的将VIC0VECTADDR0的值赋给VIC0ADDRESS并跳转到这个地址去执 */
EINT5_VECTADDR = (int)key6_handle; __asm__( "mrc p15,0,r0,c1,c0,0\n"
"orr r0,r0,#(1<<24)\n"
"mcr p15,0,r0,c1,c0,0\n" "mrs r0,cpsr\n"
"bic r0, r0, #0x80\n"
"msr cpsr_c, r0\n"
:
:
);
}

当然还有还有IO初始化设置

 #define GPNCON (volatile unsigned long*)0x7f008830

 void button_init()
{
*(GPNCON) = 0x00000aaa; //设置按键1到按键6
}

ok6410按键中断编程,linux按键裸机的更多相关文章

  1. 专题2-通过按键玩中断\2440按键中断编程lesson2

    1.程序优化 修改Makefile 把main.c里面的mmu代码复制到mmu.c并修改如下 main.c的修改 由于在bootloader当中一般不会使用MMU,所以 main.c 加入led.c文 ...

  2. 14.linux按键驱动程序(一)

    按键驱动程序 本文学习主要包含按键硬件的实现.中断分层管理.按键定时器去抖.阻塞性驱动程序设计.这里面需要使用到混杂设备驱动和中断处理程序的内容. 一.创建按键混杂设备驱动模型 int key_ope ...

  3. Linux按键设备驱动一

    ① request_irq函数用于注册中断 int request_irq(unsigned int irq, void(*handler)(int, void*, struct pt_reg*), ...

  4. 在Linux下的中断方式读取按键驱动程序

    // 在Linux下的中断方式读取按键驱动程序 //包含外部中断 休眠 加入poll机制 // 采用异步通知的方式 // 驱动程序发 ---> app接收 (通过kill_fasync()发送) ...

  5. 字符设备驱动笔记——中断方式按键驱动之linux异常处理结构(四)

    .中断方式获取按键值 单片机: )按键按下 )cup发生中断,跳转到异常向量入口执行 )b 函数 a.保存被中断的现场 b.执行中断处理函数 c.恢复 linux: )trap_init()函数构造异 ...

  6. Linux按键驱动程序设计--从简单到不简单【转】

    本文转载自:http://blog.csdn.net/coding__madman/article/details/51399353 混杂设备驱动模型: 1. 混杂设备描述 在Linux系统中,存在一 ...

  7. Linux按键驱动程序设计详解---从简单到不简单【转】

    转自:http://blog.csdn.net/coding__madman/article/details/51399353 版权声明:本文为博主原创文章,未经博主允许不得转载. 混杂设备驱动模型: ...

  8. 15.linux按键驱动程序(二)

    linux按键驱动程序 包含内容定时器延时去抖动,阻塞型设备驱动设计 一.定时器延时去抖 按键所用开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,开关不会马上稳定地接通或断开.因而 ...

  9. 全志A33 lichee 开发板 Linux中断编程原理说明

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 本节实验目标实现按键触发中断 ...

随机推荐

  1. vmware-question

    1.网卡修改序号ip link set eth3 name eth02.解决克隆虚拟机后网卡设备无法识别启动问题的方法******************************/etc/udev/r ...

  2. Qt Connect 信号 槽

    信号和槽机制是 QT 的核心机制 .信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方.信号和槽是 QT 自行定义的一种通信机制,它独立于标准 ...

  3. Django~学习计划

    20160302 Excel,PDF 处理 GeoDjango学习:GIS编程,百度地图 Javascript 邮件系统 图像处理

  4. codeforces 493A. Vasya and Football 解题报告

    题目链接:http://codeforces.com/contest/493/problem/A 题目意思:给出两个字符串,分别代表 home 和 away.然后有 t 个player,每个playe ...

  5. 【leetcode】 Permutation Sequence (middle)

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  6. 【processing】小代码3

    鼠标响应: mouseX, mouseY 鼠标的坐标 ---------------------------------------------- void setup() { size(,); sm ...

  7. CodeSign error: code signing is required for product type Application in SDK iOS

    在真机测试的时候往往会突然出现这样一个错误,code signing is required for product type 'Application' in SDK 'iOS 7.0'  ,就是说 ...

  8. October 9th 2016 Week 41st Sunday

    No matter how resourceful you are, you can't fight fate. 人纵有万般能耐,终也敌不过天命. I find that I gradually be ...

  9. August 22nd 2016 Week 35th Monday

    Have you ever given any thought to your future? 你有没有为将来打算过呢? Have you ever given any thought to your ...

  10. 自定义UIDatePikerView

    1.添加文件GoYearMonthDayPickerView.h .m .xib.NSDate+Helper.h .m.iCarousel.h .m 2.在Lable上显示日期 UILabel *ag ...