浅谈:在设计单片机按键输入的时候,进行按键消抖是防止按键输入被CPU误读多次的必要手段。

一、按键抖动
       通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。
       抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。这是一个很重要的时间参数,在很多场合都要用到。按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。

二、按键消抖方法
1.硬件消抖:适用于按键较少时

(1)RS触发器
       图中两个“与非”门构成一个RS触发器。当按键未按下时,输出为0;当键按下时,输出为1。此时即使用按键的机械性能,使按键因弹性抖动而产生瞬时断开(抖动跳开B),只要按键不返回原始状态A,双稳态电路的状态不改变,输出保持为0,不会产生抖动的波形。也就是说,即使B点的电压波形是抖动的,但经双稳态电路之后,其输出为正规的矩形波。这一点通过分析RS触发器的工作过程很容易得到验证。

(2)电容器
       利用电容的放电延时,采用并联电容法,也可以实现硬件消抖。如图所示,由于电容两端电压不能突变,使得按键两端的电压平缓变化,直至电容充放电到达一定电压阈值时,单片机才读取到电平变化。

2.软件消抖
如果按键较多,常用软件方法消抖
(1)延时函数按键消抖
       检测出键闭合后执行一个延时程序,5ms~10ms(取决于机械特性)的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。
优点:简单方便
缺点:程序在空跑浪费CPU资源、不够精准

例子:

if(PXin(x)==KEY_PRESS)
{delay_ms(10);if(PXin(x)==KEY_PRESS){//按键处理}
}

注:如果按键是用中断方式实现的,那就更不能在中断服务函数里面使用延时函数,因为中断服务函数最基本的要求就是快进快出!

(2)定时器按键消抖
       原理:按键采用中断驱动方式,当按键按下以后触发按键中断,在按键中断中开启一个定时器,定时周期为 10ms,当定时时间到了以后就会触发定时器中断,最后在定时器中断处理函数中读取按键的值,如果按键值还是按下状态那就表示这是一次有效的按键。
如图所示:

图中 t1 ~ t3 这一段时间就是按键抖动,是需要消除的。设置按键为下降沿触发(由按键的电路决定),因此会在 t1、t2 和 t3 这三个时刻会触发按键中断,每次进入中断处理函数都会重新开器定时器中断,所以会在 t1、t2 和 t3 这三个时刻开器定时器中断。但是 t1 ~ t2 和 t2 ~ t3 这两个时间段是小于我们设置的定时器中断周期(也就是消抖时间,比如 10ms),所以虽然 t1 开启了定时器,但是定时器定时时间还没到 t2 时刻就重置了定时器,最终只有 t3 时刻开启的定时器能完整的完成整个定时周期并触发中断,我们就可以在定时器中断处理函数里面做按键处理了。
优点:节约CPU资源
缺点:消耗一个定时器

例子:

//初始化按键
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0; //PA0GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);
} //初始化按键IO中断
void EXTIX_Init(void)
{ EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  KEY_Init();GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);  //中断线0EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;             NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                NVIC_Init(&NVIC_InitStructure);
}//初始化定时器中断
void TIM3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Period = arr;   //重装载值TIM_TimeBaseStructure.TIM_Prescaler =psc;  //时钟预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_ITConfig( TIM3, TIM_IT_Update ,ENABLE );  //使能定时器溢出中断NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM3, ENABLE);
}//按键的中断处理函数
void EXTI0_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line0)!=RESET){    TIM3_Int_Init(99,7199);//72M/(7199+1)=10Khz计数频率,(99+1)/10KHz=10ms定时时间 }EXTI_ClearITPendingBit(EXTI_Line0);
}//定时器3中断处理函数
void TIM3_IRQHandler(void)
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {      if(PAin(0)==0)      //按键仍然按下{ //进行按键处理LED0=!LED0;TIM_SetCounter(TIM3,0);  //清零定时器       TIM_Cmd(TIM3, DISABLE);  //失能定时器}TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  }
}

注:
1.消抖的定时时间由按键的机械特性决定,多调试。
2.中断处理函数处理完要清除相应中断标志。
3.进行按键处理后要清零和失能定时器,否则无按键按下时也在定时。

【单片机】按键消抖及原理(硬件和软件方法详解)相关推荐

  1. 按键消抖及原理(硬件和软件方法详解)

    在设计单片机按键输入的时候,进行按键消抖是防止按键输入被CPU误读多次的必要手段. 一.按键抖动 按键接法 抖动时间的长短由按键的机械特性决定,一般为5ms-10ms.这是一个很重要的时间参数,在很多 ...

  2. stm32硬件消抖_STM32单片机按键消抖和FPGA按键消抖大全

    原标题:STM32单片机按键消抖和FPGA按键消抖大全 写在前面: 按键去抖:由上图可以看出理想波形与实际波形之间是有区别的,实际波形在按下和释放的瞬间都有抖动的现象,抖动时间的长短和按键的机械特性有 ...

  3. 单片机按键“消抖”的思考

    初学单片机时,讲到了一个按键"消抖"概念,视屏教程中只是说到要确定按键是不是真正按下,所以需要加一个延时来判断. 附上延时消抖程序代码: 代码1 void keypros() {i ...

  4. stm32 工业按键检测_STM32单片机按键消抖和FPGA按键消抖大全

    写在前面: 物联网STM32入门 - 直播课程 - 创客学院​www.makeru.com.cn 按键去抖:由上图可以看出理想波形与实际波形之间是有区别的,实际波形在按下和释放的瞬间都有抖动的现象,抖 ...

  5. 51单片机按键消抖方式总结

    尊重他人劳动成果,请勿转载!!! 电路图如下: MCU采用89C52单片机,晶振12MHZ. 1.没有消除抖动的原始代码: #include <REGX52.H> #include < ...

  6. Linux驱动中按键消抖原理

    为什么要用定时器来做按键消抖? 用到按键就要处理因为机械结构带来的按键抖动问题,也就是按键消抖.前面的实验中都是直接使用了延时函数来实现消抖,因为简单,但是直接用延时函数来实现消抖会浪费 CPU 性能 ...

  7. verilog之按键消抖的理解

    按键在按下时会产生抖动,释放时也会产生抖动,所以在设计键盘扫描程序时必须考虑按键的消抖,我们一般只考虑按下时的抖动,而放弃对释放时抖动的消抖.抖动时间一般为20ms左右.按下的最终结果是低电平. 按键 ...

  8. 三行代码按键消抖 独立按键 矩阵按键 长按 短按 双击

    九层妖塔 起于垒土 直接跳转到三行代码 三行代码按键消抖 独立按键 矩阵按键 长按 短按 双击 一.基本理论 0.按键的常见名词:  ①按键抖动  ②按键稳定闭合时间 1.按键的扫描: 2.按键的消抖 ...

  9. FPGA---多按键消抖检测

    在学习了单按键消抖方法后,按键消抖的关键点就是20ms的延时,这一点和单片机按键消抖的思路是一样的.但是FPGA的延时需要通过寄存器计数,这个是比较消耗内部资源的.如果要检测4个按键时,最简单的方法就 ...

  10. 【FPGA】实战之按键消抖

    文章目录 一.按键消抖的原理 二.按键消抖的设计思路 三.代码部分 四.仿真验证 五.总结 一.按键消抖的原理 一般开发板上的按键都是机械按键,所以在按下的时候,会产生回弹的时刻,称为机械的弹性开关, ...

最新文章

  1. 以太坊,EOS和其他DApps的总数达到2,432,但没有大规模采用
  2. 腾讯 AI 2019这一年
  3. PHPStorm+XDebug进行调试
  4. 毕业论文 | 基于单片机的烟雾报警器设计(完整源代码、流程图、电路图)
  5. 【Top 50】中美人工智能高被引学者榜单:孙剑、何恺明、李飞飞进前5
  6. Openwrt 串口密码登入【ZT】
  7. Java开发两年:简述jvm内存模型
  8. js实现多个图片淡入淡出,框架
  9. 【经典算法】第一回:快速排序
  10. oracle sql 分区查询语句_Oracle分区表跨分区查询数据为空
  11. 【C++】凯撒密码 实现加密与解密
  12. json html api文档,jsonEditor api介绍
  13. 什么是Linux,以及Linux发行版?(update20201118)
  14. MSL、TTL、RTT
  15. java 小数位数控制
  16. JBoss无文件webshell研究
  17. 售票计算机 制票机的使用方法,铁路客运计算机售票具体操作.pdf
  18. cannot import name ‘DistanceMetric‘ from ‘sklearn.metrics‘
  19. 《30天自制操作系统》笔记----Day6
  20. 颜色 16进制表示 一一对应

热门文章

  1. docker介绍与应用
  2. Qt阅读器-ofd格式
  3. 10本深入学习Spring框架的最佳书籍和课程
  4. 最优秀的微信小程序UI组件库
  5. 这个在线抠图工具,好用又免费,告别Photoshop繁杂操作
  6. 3DS MAX 批量导出文件脚本 MAXScript 带界面
  7. 什么算法计算地图上从A点到B点的方向?
  8. python最优分箱计算iv值_基于sklearn决策树的最优分箱与IV值计算-Python实现
  9. 大数据----数据仓库架构
  10. Log4j日志输出格式