【备赛】按键消抖+长短按键区分

一、按键消抖

这里记录 状态机 + 系统滴答定时器 的方法来实现按键消抖。

这是一种非阻塞式的方式实现,比较不错。

周期性检测 → 记录时间戳 → 超时后确认 → 处理释放。

// 按键状态定义
typedef enum {KEY_STATE_IDLE,//空KEY_STATE_DEBOUNCE,//防抖KEY_STATE_PRESSED//压
} KeyState;KeyState key_state = KEY_STATE_IDLE;
uint32_t key_timestamp = 0;
void key_scan()
{//按键一switch(key_state){case KEY_STATE_IDLE://状态一if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET){key_state = KEY_STATE_DEBOUNCE;key_timestamp = HAL_GetTick();//记录当前时间戳}break;case KEY_STATE_DEBOUNCE://状态二if(HAL_GetTick() - key_timestamp >= 20){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET){key_state = KEY_STATE_PRESSED;//执行任务//led_show(1);count ++ ;}else {key_state = KEY_STATE_IDLE;}//抖动误判}break;case KEY_STATE_PRESSED://状态三if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) != GPIO_PIN_RESET){key_state = KEY_STATE_IDLE;}break;}//按键二//按键三//按键四
}

 二、区分长按键和短按键

// 状态定义(修正注释)
typedef enum {KEY_STATE_IDLE,          // 空闲KEY_STATE_PRESS_DEBOUNCE,// 按下消抖KEY_STATE_PRESSED,       // 已确认按下(等待长按触发)KEY_STATE_LONG_PRESS,    // 长按已触发KEY_STATE_RELEASE_DEBOUNCE // 释放消抖
} KeyState;KeyState key_state = KEY_STATE_IDLE;
uint32_t key_press_start_time = 0;
uint32_t key_release_start_time = 0;void key_scan() {switch(key_state) {// 初始状态:检测按下case KEY_STATE_IDLE:if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) {key_state = KEY_STATE_PRESS_DEBOUNCE;key_press_start_time = HAL_GetTick();}break;// 按下消抖(等待20ms)case KEY_STATE_PRESS_DEBOUNCE:if (HAL_GetTick() - key_press_start_time >= 20) {if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) {key_state = KEY_STATE_PRESSED; // 进入持续检测状态key_press_start_time = HAL_GetTick(); // 重置计时} else {key_state = KEY_STATE_IDLE; // 抖动误判}}break;// 已确认按下:持续检测时长case KEY_STATE_PRESSED:// 持续按下超过1秒 → 触发长按if (HAL_GetTick() - key_press_start_time >= 1000) {key_state = KEY_STATE_LONG_PRESS;count--; // 长按操作printf("Long Press Detected!\r\n");}// 检测是否提前释放else if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) != GPIO_PIN_RESET) {key_state = KEY_STATE_RELEASE_DEBOUNCE;key_release_start_time = HAL_GetTick();count++; // 单击操作printf("Short Press Detected!\r\n");}break;// 长按已触发状态case KEY_STATE_LONG_PRESS:if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) != GPIO_PIN_RESET) {key_state = KEY_STATE_RELEASE_DEBOUNCE;key_release_start_time = HAL_GetTick();}break;// 释放消抖(20ms)case KEY_STATE_RELEASE_DEBOUNCE:if (HAL_GetTick() - key_release_start_time >= 20) {key_state = KEY_STATE_IDLE;}break;}
}

三、按键消抖老方案(有问题)

一般我会用HAL_Delay();函数。

//B1按键
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET) //检测按键是否按下
{HAL_Delay(5000); // 消抖if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET) // 说明确实按下去了{执行任务while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET); // 等待按键释放	}
}

原代码问题分析

 阻塞式设计
while(HAL_GPIO_ReadPin(...)); // 卡死在这里等待释放
  • 问题:在等待按键释放时,CPU 被完全占用

  • 后果

    • 系统无法响应其他任务(如屏幕刷新、通信)

    • 若按键被意外卡住,程序将永久死锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/24672.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三轴加速度推算姿态角的方法,理论分析和MATLAB例程

三轴加速度推算三轴姿态的方法与MATLAB代码实现 文章目录 基本原理与方法概述静态姿态解算(仅俯仰角与横滚角)扩展(融合陀螺仪与加速度计)MATLAB代码 例程四元数动态姿态解算(融合加速度与陀螺仪)注意事项与扩展基本原理与方法概述 三轴加速度计通过测量重力分量在载体坐…

2025最新Flask学习笔记(对照Django做解析)

前言:如果还没学Django的同学,可以看Django 教程 | 菜鸟教程,也可以忽略下文所提及的Django内容;另外,由于我们接手的项目大多都是前后端分离的项目,所以本文会跳过对模板的介绍,感兴趣的朋友可…

HTML第二节

一.列表 1.列表的简介 2.无序列表 注:1.ul里面只能放li,不能放标题和段落标签 2.li里面可以放标题和段落等内容 3.有序列表 4.定义列表 注:要实现上图的效果需要CSS 二.表格 1.表格介绍 注:1.th有额外的效果,可以…

SpringBoot——生成Excel文件

在Springboot以及其他的一些项目中&#xff0c;或许我们可能需要将数据查询出来进行生成Excel文件进行数据的展示&#xff0c;或者用于进行邮箱发送进行附件添加 依赖引入 此处demo使用maven依赖进行使用 <dependency><groupId>org.apache.poi</groupId>&…

【Akashic Records】《命若琴弦》

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: Akashic Records 文章目录 &#x1f4af;观后感命运的无情与生命的坚持希望的火种与人生的意义虚无与活在当下生死的辩证与享受当下结语 &#x1f4af;观后感 命若琴弦 生命的意义本不在向外的寻取&#xff0c;而在…

C#调用CANoeCLRAdapter.dll文章(一)

一、引言 CANoe 是 Vector 公司开发的一款广泛应用于汽车电子开发、测试和分析的工具。CANoe CLR Adapter 允许开发者使用 C# 等.NET 语言来扩展 CANoe 的功能&#xff0c;实现更灵活、强大的自动化测试和数据处理。本指南将详细介绍如何基于 C# 进行 CANoe CLR Adapter 的开发…

运维和AI的邂逅: 让你的 ssh/terminal 智能化

运维同学很多工作其实就是在命令行里操作服务器&#xff0c;尽管目前有很多可视化的工具&#xff0c;但是命令行(ssh 登录)依然不可或缺&#xff0c;甚至依然还占据着主要工作。这意味着运维同学需要掌握大量和服务器操作系统以及shell相关的知识&#xff0c;记住大量的命令。 …

CMake小结2(PICO为例)

1 前言 之前写过一篇cmake&#xff0c;不过很简单&#xff1a;CMake小结_cmake ${sources}-CSDN博客 构建系统现在真的太多了&#xff0c;完全学不过来的感觉&#xff0c;meson&#xff0c;gardle&#xff0c;buildroot&#xff0c; Maven。。。我是真的有点放弃治疗了。之前…

使用OpenCV实现帧间变化检测:基于轮廓的动态区域标注

在计算机视觉中&#xff0c;帧间差异检测&#xff08;frame differencing&#xff09;是一种常用的技术&#xff0c;用于检测视频流中的动态变化区域。这种方法尤其适用于监控、运动分析、目标追踪等场景。在这篇博客中&#xff0c;我们将通过分析一个基于OpenCV的简单帧间差异…

机器学习01

机器学习的基本过程如下&#xff1a; 1.数据获取 2.数据划分 3.特征提取 4.模型选择与训练 5.模型评估 6.模型调优 一、特征工程&#xff08;重点&#xff09; 0. 特征工程步骤为&#xff1a; 特征提取(如果不是像dataframe那样的数据&#xff0c;要进行特征提取&#…

每日Attention学习24——Strip Convolution Block

模块出处 [TIP 21] [link] CoANet: Connectivity Attention Network for Road Extraction From Satellite Imagery 模块名称 Strip Convolution Block (SCB) 模块作用 多方向条形特征提取 模块结构 模块特点 类PSP设计&#xff0c;采用四个并行分支提取不同维度的信息相比于…

用FileZilla Server 1.9.4给Windows Server 2025搭建FTP服务端

FileZilla Server 是一款免费的开源 FTP 和 FTPS 服务器软件&#xff0c;分为服务器版和客户端版。服务器版原本只支持Windows操作系统&#xff0c;比如笔者曾长期使用过0.9.60版&#xff0c;那时候就只支持Windows操作系统。当时我们生产环境对FTP稳定性要求较高&#xff0c;比…

es-head(es库-谷歌浏览器插件)

1.下载es-head插件压缩包&#xff0c;并解压缩 2.谷歌浏览器添加插件 3.使用

健康检查、k8s探针、Grails+Liquibase框架/health 404 Not Found排查及解决

概述 健康检查对于一个pod而言&#xff0c;其重要性不言而喻。 k8s通过探针来实现健康检查。 探针 k8s提供三种探针&#xff1a; 存活探针&#xff1a;livenessProbe就绪探针&#xff1a;readinessProbe启动探针&#xff1a;startupProbe 存活探针 存活探针决定何时重启…

5个GitHub热点开源项目!!

1.自托管 Moonlight 游戏串流服务&#xff1a;Sunshine 主语言&#xff1a;C&#xff0c;Star&#xff1a;14.4k&#xff0c;周增长&#xff1a;500 这是一个自托管的 Moonlight 游戏串流服务器端项目&#xff0c;支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…

【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

122. 买卖股票的最佳时机 II 反向递推的方法

下面是将你提供的代码整理成一篇Markdown格式的博客内容&#xff1a; 股票买卖的最大利润 问题描述 给定一个整数数组 prices&#xff0c;其中 prices[i] 是股票在第 i 天的价格。你可以选择在某一天买入股票&#xff0c;并在之后的某一天卖出股票。要求计算出你能够获得的最…

详解Tomcat下载安装以及IDEA配置Tomcat(2023最新)

目录 步骤一&#xff1a;首先确认自己是否已经安装JDK步骤二&#xff1a;下载安装Tomcat步骤三&#xff1a;Tomcat配置环境变量步骤四&#xff1a;验证Tomcat配置是否成功步骤五&#xff1a;为IDEA配置Tomcat 步骤一&#xff1a;首先确认自己是否已经安装JDK jdk各版本通用安…

html中的css

css &#xff08;cascading style sheets&#xff0c;串联样式表&#xff0c;也叫层叠样式表&#xff09; css规范一般约定&#xff1a; 1.存放CSS样式文件的目录一般命名为style或css。 2.在项目初期&#xff0c;会把不同类别的样式放于不同的CSS文件&#xff0c;是为了CSS编…

前端项目配置初始化

creat-vue 安装 https://cn.vuejs.org/guide/quick-start.html 官网复制npm安装语句 cmd窗口创建文件夹 npm create vue3.12.2安装webstorm启动vue项目 https://www.jetbrains.com/webstorm/download/other.html 2024.3.2.1 安装依赖 下载包node_modules package 运行服…