当前位置: 首页 > news >正文

stm32_按键消抖_代码与流程分析

stm32按键消抖

  • 一 问题背景
  • 二 解决思路
  • 三 代码实现

一 问题背景

开关按钮:按下信号为0,正常信号为1

在按下时,表面上看我们只按了一下,但信号的传递并不是单纯的由1直接变为0。这是由于机械触点断开/闭合时会有抖动,信号如图示会在1和0之间抖动。这种抖动对人来说是感觉不到的,但对单片机来说,这段时间还是很漫长的。(摘自百度知道)

在这段抖动的时间,仍然会执行程序,进行信号的判定。造成我们写代码时,容易步入一个逻辑误区。详见下图对一次按下和松开按钮进行详细分析:
stm32


二 解决思路

思路:判定一次按钮按下无非是判定信号的01变化或10变化,然而根据上图我们必须清楚几个结论:

  • 1 按钮正常时信号稳定为1,按下按键稳定后为信号0
  • 2 按下松开的瞬间,会反复进行:010101 信号抖动,约5~10ms
  • 3 假设无外部情况干扰,只有 第2点 中的两种情况,才会导致连续的01或10的变化
  • 4 所以判定按钮是否被按下(也就是判断01交替),要同时考虑到按下和松开瞬间两种抖动情况

三 代码实现

判断一次按钮按下然后松开
方法1

    //B5引脚检测信号为0时,判断两种情况if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0){  //(1)刚按下按键发生抖动(2)上一次的按键松开发生抖动Delay_ms(20);//(1)若为1,度过按下抖动,信号稳定为0//(2)若为2,度过松手抖动,信号稳定为1if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0){ //检测信号仍为0,去掉情况(2)while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 0)) ;//(1) 松开时,检测到信号从0变1退出循环,此信号必定为松开抖动 run(); //执行对应操作,已确定按键按下然后松开。且按键松开抖动不影响本方法判定   }}	

方法2

	    //去掉方法1的第二次if判定,增加一次delay延时//B5引脚检测信号为0时,两种情况分析if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0){  //(1)刚按下按键发生抖动(2)上一次的按键松开发生抖动Delay_ms(20);//(1)若为1,度过按下抖动,信号稳定为0//(2)若为2,度过松手抖动,信号稳定为1while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 0)) ;// (1) 等待松开,检测到松开波动信号1时,退出循环//(2)立刻通过判定Delay_ms(20);//(1)度过松手抖动,信号稳定1,故情况2被检测的前提不成立,该程序不会检测到松手抖动//(2)若没有这一句Delay语句:按键松手瞬间会执行下方语句,可能会遇到:按一次按钮执行两次操作的情况run();    //只有情况(1)可以执行,能够检测一次按下按键并松开并执行对应操作}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ShardingSphere-Jdbc + Spring Security + Redis 实现简单JWT认证
  • 利用python检查磁盘空间使用情况
  • LinkedList 实现 LRU 缓存
  • 软考高级科目怎么选?软考高级含金量排序
  • WebView加载数据的几种方式
  • SQLSever 设置端口
  • 原子操作介绍
  • 【第三节】python中的函数
  • 【数据结构与算法】循环队列
  • 项目实战_表白墙(升级版)
  • IT服务运营管理中的关键考核指标
  • AI机器人:一键实现手机自动化操作
  • C++ STL adjacent_difference 用法
  • JavaScript递归菜单栏
  • GPT对话代码库——结构体与全局变量的比较,使用结构体的好处
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 【Leetcode】104. 二叉树的最大深度
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Django 博客开发教程 8 - 博客文章详情页
  • gulp 教程
  • js写一个简单的选项卡
  • Logstash 参考指南(目录)
  • SQLServer之索引简介
  • vue 配置sass、scss全局变量
  • 代理模式
  • 理解在java “”i=i++;”所发生的事情
  • 我这样减少了26.5M Java内存!
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 用Canvas画一棵二叉树
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​如何防止网络攻击?
  • ​虚拟化系列介绍(十)
  • ‌移动管家手机智能控制汽车系统
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (2020)Java后端开发----(面试题和笔试题)
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (void) (_x == _y)的作用
  • (八)Flink Join 连接
  • (备份) esp32 GPIO
  • (层次遍历)104. 二叉树的最大深度
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (九)c52学习之旅-定时器
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (南京观海微电子)——I3C协议介绍
  • (一)认识微服务
  • (转)setTimeout 和 setInterval 的区别
  • (轉)JSON.stringify 语法实例讲解
  • .net6 当连接用户的shell断掉后,dotnet会自动关闭,达不到长期运行的效果。.NET 进程守护
  • .net8.0与halcon编程环境构建
  • .NetCore部署微服务(二)