【蓝桥杯嵌入式】定时器实现按键单击,双击,消抖以及长按的代码实现
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏
🪔本系列专栏 - 蓝桥杯嵌入式_勾栏听曲_0的博客
🍻欢迎大家 🏹 点赞👍 评论📨 收藏⭐️
📌个人主页 - 勾栏听曲_0的博客📝
🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆
🎇立班超志,守苏武节,歌武穆词,做易水别。📈
目录
原理图解析
设置STM32CubeMX
按键配置
定时器配置
手搓代码
中断回调(服务)函数
按键判断函数
按键单击判断函数
按键双击判断函数
按键长按判断函数
原理图解析
我们以PB1为例来分析,假如按键没有被按下,那么PB1的电平就与左上角的VDD相等,也就是PB1 = 1;如果按键被按下,那么右下角的接地就会被导通,PB1的电平3就与GND相等,也就是PB1 = 2。
这样我们就能通过以上原理对按键进行判断,但是按键判断是一个事件触发程序,所以我们要使用定时器来使开发板能在任意时间都能对按键进行判断。因此我们再下一步设置STM32CubeMX中需要对定时器初始化。

设置STM32CubeMX
按键配置
首先我们先根据按键的原理图配置好引脚,需要注意的是,再前几篇文章中讲LCD与LED我们讲引脚都是设置为GPIO_Output,但是按键的四个引脚,我们需要设置为GPIO_input,如图:

然后在左侧选择GPIO中的按键的四个引脚,上下拉模式设为上拉,为以下状态:

定时器配置
关于定时器的详细知识点与解析可前往蓝桥杯嵌入式这篇博客,在这里我们只讲定时器的应用
如果大家有去做过省赛或国赛题目,就都会看到过对按键响应时间是有要求的,一般都是响应时间在0.1秒内,所以我们的定时器可以就设置为0.01秒。

以下是使能中断

手搓代码
中断回调(服务)函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
以下就是中断回调函数,很长,记不住怎么办。别担心,还有办法,我们打开keil5,在Project下找到stm32g4xx_it.c,在里面找到stm32g4xx_hal-tim.h并打开他,翻到最下面,再往上滑一点点,大概两千五百多行的位置,就可以找到这个函数啦,我们就可以直接复制使用。



按键判断函数
实现创建一个按键的结构体,其含义写在注释中了:
struct keys
{uchar judge_sta; //判断按键按键按下的动作到了第几步bool key_sta; //如果按键被按下,为0bool key_flag; //如果确认被按下,为1
};
具体实现按键判断函数的思路:
1.判断中断回调函数收到的中断信号是不是我们刚刚给按键设置的定时器3的信号,如果是就进入按键判断函数
2.读取每个按键这一时刻的电平
3.判断有哪些按键为按下的状态(低电平)
4.按键抖动判断
5.状态重置
按键单击判断函数
具体实现代码如下,代码中也有详细注释,希望能有所帮助:
struct keys key[4]={0,0,0,0};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3) //判断中断信号是否来自定时器3{key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); //读按键PB0现在的状态,如果被按下,PB0 = 0;如果没有被按下,PB0 = 1;key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i = 0;i < 4; i++ ) //确认是哪个或哪些按键被按下了{switch (key[i].judge_sta){case 0:{if(key[i].key_sta==0) key[i].judge_sta = 1; //第一次判断是否按下}break;case 1:{if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖{key[i].judge_sta = 2;key[i].key_flag = 1;}else //否则就是抖动,本次不算按键被按下key[i].judge_sta = 0;}break;case 2:{if(key[i].key_sta==1) key[i].judge_sta = 0; //判断是否松手,松手后按键状态重置}break;}}}
}
按键双击判断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3) //判断中断信号是否来自定时器3{key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); //读按键PB0现在的状态,如果被按下,PB0 = 0;如果没有被按下,PB0 = 1;key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i = 0;i < 4; i++ ) //确认是哪个或哪些按键被按下了{switch (key[i].judge_sta){case 0:{if(key[i].key_sta==0) key[i].judge_sta = 1; //第一次判断是否按下}break;case 1:{if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖{if(a == i && key[a].key_time < 70) //小于70,说明上次按下后到这次按下时间间隔小于0.7秒{key[i].double_key_flag = 1; //这是一次双击事件}else{key[i].key_flag = 1;a = i; //记录这一次是上面按键被按下}key[i].judge_sta = 2;}else //否则就是抖动,本次不算按键被按下key[i].judge_sta = 0;}break;case 2:{if(key[i].key_sta==1) key[i].judge_sta = 0; //判断是否松手,松手后按键状态重置key[i].key_time = 0;}break;}}key[a].key_time++; //第一次被按下之后,开始计时}
}
按键长按判断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i = 0;i < 4; i++ ){switch (key[i].judge_sta){case 0:{if(key[i].key_sta==0) {key[i].judge_sta = 1; //第一次判断是否按下key[i].key_time = 0;}}break;case 1:{if(key[i].key_sta==0) //进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖{key[i].judge_sta = 2;}elsekey[i].judge_sta = 0;}break;case 2:{ if(key[i].key_sta==1) //判断是否松手{if(key[i].key_time < 100){key[i].key_flag = 1;}
// if(key[i].key_time > 100) //一次扫描10毫秒,100次1000毫秒,就是判断是否长按超过1000毫秒
// //松手后,才会执行相应反应
// {
// key[i].long_flag = 1;
// }key[i].judge_sta = 0; }else{key[i].key_time++;if(key[i].key_time > 100) //一次扫描10毫秒,100次1000毫秒,就是判断是否长按超过1000毫秒//未松手时,就会执行相应反应{key[i].long_flag = 1;}}}break;}}}
}
相关文章:
【蓝桥杯嵌入式】定时器实现按键单击,双击,消抖以及长按的代码实现
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...
基于SSM的Javaweb爱心扶贫捐赠系统
文章目录 项目介绍主要功能截图:后台登录首页个人中心用户管理扶贫物资管理扶贫产品管理留言板管理前台前台首页扶贫产品新闻资讯留言板部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,…...
Spring Cloud(微服务)学习篇(三)
Spring Cloud(微服务)学习篇(三) 1 nacos中使用openFeign(调用方式)实现短信发送 1.1 在shop-sms-api中创建com.zlz.shop.sms.api.service/vo/dto/util,目录结构如下所示 1.2 在pom.xml(shop-sms-api)中加入如下依赖 <dependencies><dependency><groupId>…...
一文带你吃透JSP,增删改查实战案例详细解读
文章目录前言JSP 概述JSP快速入门搭建环境导入JSP依赖创建 JSP 页面编写代码测试JSP原理JSP 脚本实战案例JSP缺点发展阶段EL 表达式概述实战案例域对象JSTL 标签用法1用法2前言 不得不说,JSP 现在已经是一门十分老旧的技术了,学习编程时,不仅…...
taobao.item.propimg.upload( 添加或修改属性图片 )
¥开放平台基础API必须用户授权 添加一张商品属性图片到num_iid指定的商品中 传入的num_iid所对应的商品必须属于当前会话的用户 图片的属性必须要是颜色的属性,这个在前台显示的时候需要和sku进行关联的 商品属性图片只有享有服务的卖家(如&a…...
TDEngine集群监控组件安装配置(Telegra+Grafana方案)
Tdengine的监控指标包括以下几个方面: 系统指标:CPU使用率、内存使用率、磁盘空间、网络流量等。数据库指标:连接数、查询数、写入数、读取数等。SQL指标:执行时间、执行计划、索引使用情况等。集群指标:节点状态、数…...
【定位】高德地图wifi定位接口使用效果实践
高德地图wifi定位接口使用效果实践 背景 目的是基于高德地图wifi定位接口实现在高德地图上展示终端设备的位置和轨迹。 原理 为了将原理阐述的稍微直白一点,特意使用UML图表产生下面的一个序列图: #mermaid-svg-iHgWizHiUSRqCWdF {font-family:"trebuchet ms",…...
Nacos注册中心
目录 认识和安装Nacos 启动方式 Nacos快速入门 提示 Nacos服务分级存储模型 服务跨集群调用问题 管理端设置策略 总结 Nacos环境隔离 如何创建 使用方式 编辑 总结 Nacos注册中心分析 临时实例和非临时实例 定义 配置方式 总结 认识和安装Nacos Nacos是Sp…...
Liunx常用命令总结
常用命令arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性 hdparm -tT /dev/sda 在磁盘上执行测试性读取操作 cat /proc/cpuinfo …...
MySQL表的增删查改(进阶)
所有操作:主要讲了数据库的约束,表之间的关系,新增,聚合查询,联合查询等内容。是一篇博客所有操作的记录。 844d186 风夏/mysql_learning - Gitee.com数据库约束1.1 约束条件not null -指定某个列不能储存null值。un…...
【RocksDB】Ubuntu20.04下编译rocksdb
前言: 我在刚学rocksdb的时候是在2022年,但是网上的资源很少,查了好久才把rocksdb安装成功,在这里向大家分享一下我的经历,安装过程中也报了很多错误,希望大家不要迷路 首先 在虚拟机里面安装依赖的包以…...
这可能是Spring Boot Starter 讲的最清楚的一次了
Spring Boot Starter 是 Spring Boot 中非常重要的一个功能,它可以帮助开发人员快速集成各种第三方库和框架。本文将从 Spring Boot Starter 的基本概念入手,深入讲解 Spring Boot Starter 的实现原理及其应用场景。 一、Spring Boot Starter 的概念 S…...
activiti7执行流程详解
什么是工作流? 官方定义:工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触发顺序和触发条件,每个任务可以由一个或多个软件系统完成,也可以由一个或一组人完成,还可以由一个或多个人与软件系统…...
iframe页面传值取值
业务:目标界面的是用原生js写的 , 被镶嵌到vue平台上 , 现在要求vue点击跳转的时候 ,要附带上值 ,让原生界面获取到值 , 完成页面设置查询。 想法 : vue跳转,使用this.$route.qu…...
2023年2月安全事件盘点
一、基本信息 2023年2月安全事件共造成约3796万美元损失,相较于上个月,安全事件数量与损失金额都有显著上升,其中Platypus Finance闪电贷攻击为单次利用损失之最高达850万美元。本月RugPull数量基本与上月持平,损失金额占比显著降…...
2023上海国际电商物流包装产业展览会相约上海
2023年7月5-7日 | 上海新国际博览中心 同期举办:2023上海国际快递物流产业博览会 指导单位:上海市邮政管理局 中国快递协会 主办单位:上海市快递行业协会 上海市仓储与配送行业协会 上海市物流协会 承办单位:上海信世展览服务有…...
营业执照注册资本是什么意思
一、营业执照注册资本是什么意思 营业执照上的注册资本是指合营企业在登记管理机构登记的资本总额,是合营各方已经缴纳的或合营者承诺一定要缴纳的出资额的总和。我国法律、法规规定,合营企业成立之前必须在合营企业合同、章程中明确企业的注册资本&…...
GB28181协议--SIP协议介绍
1、SIP协议简介 SIP(Session Initiation Protocol,会话初始协议)是一个用于建立、更改和终止多媒体会话的应用层控制协议,其中的会话可以是IP电话、多媒体会话或多媒体会议(GB28181安防使用的是SIP协议)。S…...
Python3 入门教程||Python3 元组||Python3 字典
Python3 元组 Python 的元组(tuple,简写为tup)与列表类似,不同之处在于元组的元素不能修改。 元组使用小括号(),列表使用方括号[]。 元组创建很简单,只需要在括号中添加元素,并使用逗…...
多元统计方法众多,分类还是排序?约束排序还是非约束排序?哪种方法或技术更适合我的研究目的或数据?
生态环境领域研究中常常面对众多的不同类型的数据或变量,当要同时分析多个因变量(y)时需要用到多元统计分析(multivariate statistical analysis)。多元统计分析内容丰富,应用广泛,是非常重要和…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
