一、按键抖动的现象

按键按下和松开的时候,按键金属片之间的贴合、分离有一个过程。给STM32输入的信号并不是理想的0和1切换的过程。而是如下图所示的,按下和松开的一小段时间内按键信号出现抖动(jitter),这种现象称为按键抖动(Button Bouncing)。为了避免程序上出现误动作,需要从硬件或软件上消除按键抖动(Button Debouncing)。


二、 硬件电路消抖

可以从电路设计上消除抖动,常见的有RC滤波电路消抖。但是仅通过RC电路,消抖过程慢,实际效果也并不好,一般会加上施密特触发器。硬件消抖的缺点是要增加额外的元器件,如果有多个需要消抖的输入信号,则会增加较大的成本。

  • RC电路

  • RC电路加施密特触发器

三、 软件消抖

3.1 按键状态分析

按键状态变化后,短时间内的状态是抖动的、不可采用的。软件上可延迟一段时间再判断按键的状态。按键的状态机变化如下图所示。

3.2 程序实现

下面通过程序来实现按键的消抖。下例中的开发板MCU为stm32f103RCT6, 按键接在PB12、PB13引脚,LED接在PC0、PC1引脚。程序基于HAL库编写,外设的初始化程序由Stm32CubeMx软件生成,此处不再赘述。

  • 循环阻塞判断
int main(void)
{while (1){if (HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_RESET){HAL_Delay(20);if(HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_RESET){printf("Key 1 pressed.\n");HAL_GPIO_TogglePin(Led1_GPIO_Port, Led1_Pin);while(HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_RESET);      // 等待按键松开}}}
}

上面的方式,按键松开之前程序一直卡在while循环里,按键松开之后才能处理其他的程序。


  • 增加标志位、非阻塞
int main(void)
{uint8_t Button1PressedFlag = 0;uint8_t Button2PressedFlag = 0;while (1){if (Button1PressedFlag == 0 && HAL_GPIO_ReadPin(Button1_GPIO_Port == Button1_Pin) == GPIO_PIN_RESET){HAL_Delay(20);if(HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_RESET){printf("Key 1 pressed.\n");HAL_GPIO_TogglePin(Led1_GPIO_Port, Led1_Pin);Button1PressedFlag = 1;}}if(Button1PressedFlag == 1 && HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_SET){HAL_Delay(20);if(HAL_GPIO_ReadPin(Button1_GPIO_Port, Button1_Pin) == GPIO_PIN_SET){printf("Key 1 released.\n");Button1PressedFlag = 0;}}if (Button2PressedFlag == 0 && HAL_GPIO_ReadPin(Button2_GPIO_Port, Button2_Pin) == GPIO_PIN_RESET){HAL_Delay(20);if(HAL_GPIO_ReadPin(Button2_GPIO_Port, Button2_Pin) == GPIO_PIN_RESET){printf("Key 2 pressed.\n");HAL_GPIO_TogglePin(Led2_GPIO_Port, Led2_Pin);Button2PressedFlag = 1;}}if(Button2PressedFlag == 1 && HAL_GPIO_ReadPin(Button2_GPIO_Port, Button2_Pin) == GPIO_PIN_SET){HAL_Delay(20);if(HAL_GPIO_ReadPin(Button2_GPIO_Port, Button2_Pin) == GPIO_PIN_SET){printf("Key 2 released.\n");Button2PressedFlag = 0;}}}
}

上面实现的是两个按键消抖的处理。非阻塞方式可实现两个LED灯的同时点亮和熄灭,阻塞方式只能一个一个地操作。


  • 外部中断方式
    ①. 将按键GPIO设置为外部中断输入方式,中断捕获类型可根据实际电路设置为上升沿或下降沿,这里我们配置为内部上拉、下降沿中断方式。

    ②. 设置中断优先级,打开中断

    ③. 在stm32f1xx_it.c文件中编写中断回调函数
void EXTI15_10_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}       // EXTI15_10_IRQHandler 中断ISR 有CubeMx生成void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_12){printf("Button triggered!\n");HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET){HAL_GPIO_TogglePin(Led1_GPIO_Port, Led1_Pin);printf("Led toggled!\n");}}if(GPIO_Pin == GPIO_PIN_13){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == GPIO_PIN_RESET){HAL_GPIO_TogglePin(Led2_GPIO_Port, Led2_Pin);}}
}       // 中断回调函数 按键按下之后执行的动作由自己编写

   ⑤. 最后,还需修改一下HAL库中的外部GPIO中断服务函数

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{/* EXTI line interrupt detected */if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u){
//    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);    注释此行HAL_GPIO_EXTI_Callback(GPIO_Pin);__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);     // 添加此行}
}

关于中断消抖的方式,有几个需要注意的点。以上只是实现过程的描述,具体细节下一篇更新

STM32按键消抖的几种实现方式-STM32 Button Debouncing相关推荐

  1. STM32按键消抖——入门状态机思维

    在嵌入式软件开发中,状态机编程是一个十分重要的编程思想,它也是嵌入式开发中一个常用的编程框架.掌握了状态机编程思想,可以更加逻辑清晰的实现复杂的业务逻辑功能. 1 状态机思想 状态机,或称有限状态机F ...

  2. 28335学习笔记4——F28335之3*3按键控制(包含按键消抖和按键检测方法介绍)

    1.按键消抖 通常的按键所用开关为机械弹性开关,当机械触点断开. 闭合时, 电压信号如下图所示 由于机械点的弹性作用,按键开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开.在闭合和断开的瞬间均 ...

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

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

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

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

  5. 一种相对高效的按键消抖方法

    按键软件消抖自我接触单片机开始就已经存在这个问题了,网上的办法无非是延时消抖和定时轮询.对于写裸机的我来说这两种方法都不可避免的会有资源浪费掉,今天突然有了灵感,想到了一种相对高效的办法来解决消抖问题 ...

  6. F28335矩阵键盘的3种工作方式代码及按键消抖讨论(包括利用GPIO输入量化实现按键消抖)

    文章目录 前言 1. 延时消抖 1.1 硬件电路 1.2 3种工作方式的代码 2. 利用GPIO输入量化实现按键消抖 2.1 理论分析 2.1 代码分析 前言 本文是在学习普中TMS320F28335 ...

  7. stm32硬件消抖_在 STM32 上使用 C++ 指南

    结识更多同行,共同讨论"嵌入式"技术.欢迎添加社区客服微信,备注发送"电源+公司名(学校)+职位(专业)"拉您入群. 简介 本文描述了如何使用在搭载了 RT-T ...

  8. ARM(I.MX6ULL) EPIT定时器中断实验、定时器按键消抖

    参考:Linux之ARM (I.MX6ULL) EPIT定时器详解 作者:一只青木呀 发布时间: 2020-09-20 10:03:37 网址:https://blog.csdn.net/weixin ...

  9. 《按键消抖与LED控制》实验的个人思考与总结

    2019/01/08,第一个判断是否有按键按下的操作好像有问题,有空在修改! 红色为修改部分: 问题描述: 当三个独立按键的某一个被按下后,相应的LED被点亮:再次按下后,LED熄灭,按键控制LED亮 ...

最新文章

  1. warpPerspective函数
  2. 周五话运营 | 做个了解用户的精细化运营喵
  3. 同步中断和异步中断区别
  4. Spring系列(六):@Conditional注解用法介绍
  5. zookeeper 负载_ZooKeeper,策展人以及微服务负载平衡的工作方式
  6. java如何快速抛出异常,异常 - 如何抛出异常 - 《Java 编程要点(Essential Java)》 - 书栈网 · BookStack...
  7. 阿里云服务器对外开放tomcat端口访问
  8. mysql主从之slave-skip-errors和sql_slave_skip_counter
  9. [线筛五连]线筛素数
  10. 《python核心编程》学习笔记
  11. VUE微信开放平台实现网站微信登陆
  12. java 阴阳历,Java基础-有意思的阴阳历互换的算法
  13. 解决方案:Browserslist:caniuse-lite is outdated. Please run next command `npm update`
  14. 博弈论:零和博弈与常和博弈的区别
  15. Metasploitable2虚拟机镜像下载地址
  16. [免费专栏] Android安全之数据存储与数据安全「详解」
  17. 代码块:在Java中,使用{}括起来的代码被称为代码块。
  18. Unity3D——学习分享(二) 给游戏对象添加材质和贴图
  19. 在mac上通过Homebrew安装redis
  20. 微波射频学习笔记3--------微带线与带状线介绍

热门文章

  1. XP退役也是一次系统升级换代的好机会
  2. 职场新人应该如何为人处世:踏实做事,诚实做人
  3. PPDE第二季度迎新 | 欢迎22位AI开发者加入飞桨开发者技术专家计划!
  4. 一个程序员的江湖传奇
  5. ad下发统一桌面出现黑屏
  6. 数字信号处理_ 第2个编程实例
  7. BGP实验,MPLS多协议标签交换防路由黑洞
  8. python中globals_Python 中 globals() 函数的使用
  9. python算法简单了解
  10. 想给自己的实景三维模型做个案例集?Wish3D Earth再合适不过了