以下内容源于朱有鹏嵌入式课程的学习,以及博客http://www.cnblogs.com/biaohc/p/6353954.html的学习整理,如有侵权,请告知删除。

一、按键

1、按键的物理特性

  • 按钮没有被按下时,内部是断开的。
  • 按钮被按下时,内部保持接通(闭合)状态;如果放手,则由于弹簧作用,按钮又被弹开,内部断开。
  • 一般按键有4个引脚,分成2对:一对是常开触点(像上面描述的不按则断开,按下则闭合);一对是常闭触点(平时不按时是闭合的,按下后是断开的)。

2、按键的电学原理(结合原理图分析)

(1)硬件接法: SW5:GPH0_2,SW6:GPH0_3,SW78910:GPH2_0123;

(2)按键的电路连接分析

  • 按钮没有按下,则按钮内部断开,GPIO引脚处电压为高电平;
  • 按钮被按下时,则按钮内部导通,外部VDD经过电阻和按钮连接到地,形成回路,此时GPIO引脚处电压就变成了低电平。

(3)总结

  • 按键的按下与弹开,分别对应GPIO的两种电平状态(按下则GPIO为低电平,弹开则GPIO为高电平)。
  • SoC内部通过检测这个GPIO的电平高低来判断按键是否被按下,这个判断结果即可作为SoC的输入信号。

3、按键属于输入类设备

按键一般用来做输入设备(向SoC发送信息的设备,叫输入设备),由人向SoC发送按键信号(按键信号有2种:按下信号和弹开信号)。

  • 有些设备是单纯的输入设备,譬如按键、触摸屏等;
  • 有些设备是单纯的输出设备,譬如LCD;
  • 有些设备是既能输入又能输出的,叫输入输出设备(IO),譬如串口。

4、按键的2种处理方式

SoC处理按键有2种思路:轮询方式和中断方式。

  • 轮询方式:SoC每隔一段时间去读取(按键所对应的)GPIO的电平高低,以此获得按键信息;缺点在于CPU要一直注意按键事件,会影响CPU做其他事情。
  • 中断方式:SoC事先设定好GPIO触发的中断所对应的中断处理程序ISR,当按键按下或弹开时会触发GPIO对应的外部中断,导致ISR执行,从而自动处理按键信息。

二、轮询方式处理按键

1、X210开发板的按键接法

  • 由原理图可以看出:按下时是低电平,弹起时是高电平

2、按键对应的GPIO模式设置

  • 按键接到GPIO上,按键按下还是弹起,决定外部电路的接通与否,从而决定这个GPIO引脚的电压是高还是低;
  • 这个电压可以作为这个GPIO引脚的输入信号,此时GPIO配置为输入模式,即可从SoC内部读取该引脚的电平为1还是0(1对应高电平,0对应低电平)。
  • GPH0CON(0xE0200C00),GPH0DAT(0xE0200C04),GPH2CON(0xE0200C40),GPH2DAT(0xE0200C44)。
  • 在CON寄存器中将GPIO设置为input模式,然后读取DAT寄存器:读取到的相应位的值为1表示外部是高电平,读取到的位的值为0表明外部是低电平。
  • GPH0CON的每4bit(GPH0CON[?])控制GPH0的一个引脚(引脚?)的模式。

3、轮询方式处理按键的程序流程

  • 第一步,先初始化GPIO模式为input;
  • 第二步,循环读取GPIO的电平值,然后判断有无按键按下;

4、轮询方式检测有无按键

/**        s5pv210裸机实验*        *        key**/#define _REG_GPH0CON            (*(volatile unsigned int *)0xE0200C00)
#define _REG_GPH0DAT            (*(volatile unsigned int *)0xE0200C04)
#define _REG_GPH2CON            (*(volatile unsigned int *)0xE0200C40)
#define _REG_GPH2DAT            (*(volatile unsigned int *)0xE0200C44)void led_blink(void);
void led_off(void);void key_init(void)
{//EINT2配置为输入模式_REG_GPH0CON &= ~(0xFF<<8);    //GPH2_0~GPH2_3置为输入_REG_GPH2CON &= ~(0xFFFF<<0);}void key_polling(void)
{key_init();while (1) {
//由于通过_REG_GPH0CON设置GPH0_2这个引脚为输入模式,
//_REG_GPH0DAT这个寄存器对应的位就是对应引脚的值if (!(_REG_GPH0DAT & (0x1<<2))) {led_blink();}if (!(_REG_GPH0DAT & (0x1<<3))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<0))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<1))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<2))) {led_blink();}if (!(_REG_GPH2DAT & (0x1<<3))) {led_blink();}}}

三、外部中断

1、什么是外部中断?数据手册在哪里?

(1)SoC支持的中断类型中有一类叫外部中断。

  • 内部中断,指中断源来自于SoC内部(一般是内部外设),譬如串口、定时器等部件产生的中断;
  • 外部中断是SoC外部的设备,通过外部中断对应的GPIO引脚产生的中断。

(2)按键在SoC中就使用外部中断来实现。

  • 将按键电路接在外部中断的GPIO上,然后将GPIO配置为外部中断模式。
  • 此时通过按按键改变按键电路的电压高低,这个电压高低会触发GPIO对应的外部中断,通过引脚传进去给CPU处理。

2、电平触发和边沿触发

  • 外部中断的触发模式主要有2种:电平触发和边沿触发。
  • 电平触发:电平触发分为高电平触发和低电平触发。电平触发的特点是,只要电平满足条件就会不停触发中断。
  • 边沿触发分为上升沿触发、下降沿触发和双边沿触发三种。边沿触发不关心电平常规状态,只关心电平变化的瞬间(边沿触发不关心电平本身是高还是低,只关心变化是从高到低还是从低到高的这个过程)。如果关注的是按键按下和弹起这两个事件本身,那么应该用边沿触发来处理按键;如果关心的是按键按下/弹起的那一段时间,那么应该用电平触发。

3、关键寄存器:CON、PEND、MASK

(1)外部中断设置需要涉及到4个寄存器

  • 接线引脚要设置为中断模式;(通过对应的GPIO控制寄存器,比如GPH0是通过GPH0CON寄存器控制的)
  • 设置中断触发的方式;
  • 中断掩码设置为使能中断;
  • 中断挂起要设置为0,发生中断以后,中断处理函数要把中断挂起为重新写为0;

(2)GPH0CON寄存器

  • 接入中断的引脚要设置为EXT_INT中断模式;

(3)EXT_INT_0_CON寄存器

  • 配置外部中断的触发方式。触发方式就是说外部电平怎么变化就能触发中断,也就是说这个外部中断产生的条件是什么。

(4)EXT_INT_0_PEND寄存器(中断挂起寄存器)

  • 每一位对应一个外部中断,没有中断时值为0。
  • 发生中断后,硬件自动将此寄存器中该中断对应的位置1,我们去处理完这个中断后应该手工将该位置0。
  • PEND寄存器的位相当于一个标志,如果发生了中断暂时忙来不及去处理时,这个位一直是1(这就是挂起),直到处理了此中断才会手工清除(写代码清除)这个挂起位,表示此中断被处理了。

(5)EXT_INT_0_MASK寄存器

  • 各个外部中断的使能/禁止开关。
  • EXT_INT_0_MASK:中断掩码要设置为0。

4、中断方式处理按键

#define EXT_INT_0_CON    0xE0200E00
#define EXT_INT_2_CON    0xE0200E08
#define EXT_INT_0_PEND    0xE0200F40
#define EXT_INT_2_PEND    0xE0200F48
#define EXT_INT_0_MASK    0xE0200F00
#define EXT_INT_2_MASK    0xE0200F08#define _REG_EXT_INT_0_CON    (*(volatile unsigned int *)EXT_INT_0_CON)
#define _REG_EXT_INT_2_CON    (*(volatile unsigned int *)EXT_INT_2_CON)
#define _REG_EXT_INT_0_PEND    (*(volatile unsigned int *)EXT_INT_0_PEND)
#define _REG_EXT_INT_2_PEND    (*(volatile unsigned int *)EXT_INT_2_PEND)
#define _REG_EXT_INT_0_MASK    (*(volatile unsigned int *)EXT_INT_0_MASK)
#define _REG_EXT_INT_2_MASK    (*(volatile unsigned int *)EXT_INT_2_MASK)//中断方式初始化按键
void key_inter_init(void)
{//ENIT2、ENIT3引脚设置为中断模式_REG_GPH0CON |= (0xFF<<8);//ENIT16、ENIT17、ENIT18、ENIT19引脚设置为中断模式_REG_GPH2CON |= (0xFFFF<<0);//设置ENIT2、ENIT3为下降沿触发_REG_EXT_INT_0_CON &= ~(0xFF<<8);_REG_EXT_INT_0_CON |= ((0x2<<8) | (0x2<<12));//设置ENIT16、ENIT17、ENIT18、ENIT19为下降沿触发_REG_EXT_INT_2_CON &= ~(0xFFFF<<0);_REG_EXT_INT_0_CON |= ((0x2<<0) | (0x2<<4) | (0x2<<8) | (0x2<<12));//使ENIT2、ENIT3能外部中断;_REG_EXT_INT_0_MASK &= ~(0x3<<2);//使ENIT16、ENIT17、ENIT18、ENIT19能外部中断;_REG_EXT_INT_2_MASK &= ~(0xF<<0);/*    //清ENIT2、ENIT3中断挂起_REG_EXT_INT_0_PEND |= (0x3<<2);//清ENIT16、ENIT17、ENIT18、ENIT19中断挂起_REG_EXT_INT_2_PEND |= (0xF<<0);*/clean_int_pend();
}

总结:

(1)由于按键的连接方式,知按键是连接到GPH0和GPH1的。

以GPH0为例,接了按键eint1、enit2。可以通过GPH0CON寄存器控制GPH0每个引脚的模式(输出、输入、中断)。如果是中断,可知eint1和eint2的中断号分别为2,3,可以统一看做是中断组号0下的中断,因此是在ext_int_0_前缀的寄存器下继续进行触发条件的设置(EXT_INT_0_CON寄存器),以及是否启用中断的设置(EXT_INT_0_MASK寄存器)。由于是中断2,3,因此设置的是2,3中断对应的位([]中为2,3的)。

附:串口输出和按键消抖

1、基于串口标准输出的按键调试

  • 以之前的串口stdio的工程为基础来移植添加轮询方式按键处理。
  • 注意USB下载方式可能有错误(有可能不下载,也有可能下载了执行不对),解决方案是用SD卡启动来替代。

2、按键消抖

(1)按键这种物理器件本身会有抖动信号

  • 抖动信号指的是在电平由高到低(也就是按键按下时)或者电平由低到高(也就是按键弹起时)过程中,电平的变化不是立刻变化,而是经过了一段时间的不稳定期才完成变化,在这个不稳定期间电平可能会时高时低反复变化,这个不稳定期就叫抖动。
  • 抖动期内获取按键信息是不可靠的,要想办法消抖。

(2)什么叫消抖?

  • 消抖就是用硬件或者软件方法来尽量减小抖动期对按键获取的影响。
  • 第一是硬件消抖,消抖思路就是尽量减小抖动时间,方法是通过硬件添加电容等元件来减小抖动;
  • 第二是软件消抖,消抖思路是发现一次按键按下/弹起事件后,不立即处理按键,而是延时一段时间(一般10~20ms,这就是消抖时间)后再次获取按键键值,如果此次获取和上次一样是按下/弹起,那就认为真的按下/弹起了。
  • 一般比较精密需要的时候,需要硬件消抖和软件消抖一起配合。

s5pv210——按键相关推荐

  1. S5PV210按键POLL实现机制

    驱动程序: #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #inc ...

  2. S5PV210 按键驱动源码、应用程序解析(重点:中断、休眠唤醒、定时器)

    按键驱动是最简单的功能,一旦使用linux来做就需要做很多功课.anyway,逻辑层还是前年不变的.先贴上驱动层代码. /** linux/drivers/char/mini210_buttons.c ...

  3. ARM之S5pv210的按键和中断部分

    一.按键和中断分析 要使用中断,首先要做好两个部分的工作:CPU中断的初始化和相应器件的中断的初始化. CPU中断初始化:就是要设置号CPU有关中断的东西. 相关器件的中断初始化:例如按键,就要设置好 ...

  4. 裸机篇 -- S5PV210的中断体系

        本帖主要通过外部中断实验来学习S5PV210的中断体系. S5PV210的中断体系结构 在官方datasheet -- S5PV210_UM_REV1.1 中的sections 04_inte ...

  5. 驱动程序实例(四):按键驱动程序(platform + input子系统 + 外部中断方式)

    结合之前对Linux内核的platform总线与input子系统的分析 ,本文将编写基于platform总线和input子系统的Button设备的实例代码并对其进行分析. platform总线的分析, ...

  6. s5pv210——中断实战

    以下内容源于博客http://www.cnblogs.com/biaohc/p/6354068.html的学习,以及朱有鹏老师课程的学习,和网络资源的整理. 一.s5pv210的中断步骤 (1)建立异 ...

  7. TQ210——S5PV210中断体系

    TQ210--S5PV210中断体系 中断是指 CPU 在执行程序的过程中,遇到异常情况需要处理, CPU停 止当前程序的运行,保存当前程序运行处的必要参数,转去处理这些异常情况, 处理结束后再返回当 ...

  8. S5PV210 Uboot开发与移植03:Uboot启动流程详解

    目录 1. start.S解析 1.1 uboot入口分析 1.2 头文件包含 1.2.1 config.h 1.2.2 version.h 1.2.3 asm/proc/domain.h 1.2.4 ...

  9. S5PV210体系结构与接口09:SD卡启动详解

    目录 1. MMC技术演进 1.1 NandFlash & NorFlash芯片 1.2 MMC卡 & SD卡 & MicroSD卡(TF卡) 1.2.1 代际关系 1.2.2 ...

最新文章

  1. vivo 全球商城:商品系统架构设计与实践
  2. 30~60万|项目需求——胳膊与手指的动态识别技术
  3. 零售业创新服务:Kochhaus杂货店按照菜谱陈列商品
  4. 多线程与网络之NSURLConnection发送请求
  5. 切记:只有肯吃苦才能赚大钱!
  6. 周正宁:未来五年属于WebRTC+AV1
  7. ES6 解构赋值详解
  8. 罗永浩或将找陈冠希做代言人
  9. 区块链 以太坊 solidity 事务控制和异常处理 require assert
  10. subprocess解决僵尸进程
  11. android将彩图转为黑白_android 将图片转换成黑白图片
  12. BIMC指出企业发展电子商务的问题
  13. c51语言主函数,51单片机的基本c51语言程序介绍
  14. 在 Debian 11 Bullseye 上安装 Proxmox VE 7国内镜像源
  15. 生存分析——cox模型及相关参数求解
  16. 二硫化钼量子点修饰纳米金棒/CdS纳米棒|二硫化钼量子点/g-C3N4复合光催化剂|马来酰亚胺修饰二硫化钼MoS2-MAL
  17. 配置 Rails 应用程序
  18. Flutter进阶—通用布局控件
  19. Django:将有存量数据的自定义的用户表无痛继承自带的AbsUser
  20. 故宫景点功课17:内廷西路(中)

热门文章

  1. 跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击
  2. 部署WEB项目到服务器(三)安装mysql到linux服务器(Ubuntu)详解
  3. 奇怪的bug,不懂Atom在添加markdown-themeable-pdf,在配置好phantomjs的情况下报错
  4. sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
  5. java web service简单示例
  6. 将中文标点符号替换成英文标点符号
  7. JVM(一)史上最佳入门指南
  8. 【附源码】为了帮助程序员谈恋爱,我做了这个APP
  9. 【学习笔记】在storyboard中给TabViewController添加tab页面
  10. 如何打开pr_debug调试信息