单片机按键消抖常用的软硬件方法
一:什么是开关抖动?
当我们按下按钮或拨动开关或微动开关时,两个金属部件会接触以短路电源。但它们不会立即连接,而是金属部件在实际稳定连接之前连接和断开几次。释放按钮时也会发生同样的事情。这会导致误触发或多次触发,例如多次按下按钮。这就像一个弹跳的球从高处落下,它一直在表面弹跳,直到它静止。
换句话说,我们可以说开关弹跳是任何开关的非理想行为,它会生成单个输入的多个转换。当我们处理电源电路时,开关弹跳不是主要问题,但当我们处理逻辑或数字电路时,它会引起问题。因此,为了消除电路中的抖动,使用了开关去抖动电路。
二:电路及波形
首先,我们将演示没有开关去抖动的电路
通过示波器抓取信号的波形如下:
您还可以在按下按钮时在示波器中看到波形。它显示在按钮切换期间发生了多少弹跳。
三:硬件去抖动
防止电路开关弹跳的常用方法有3种。
硬件去抖
RC 去抖
开关去抖IC
在硬件去抖动技术中,我们使用 S-R 触发器来防止电路发生开关抖动。这是所有方法中最好的去抖动方法。
该电路由两个与非门(74HC00 IC)组成,形成一个 SR 触发器。正如您在电路图中看到的,只要拨动开关切换到 A 侧,输出逻辑就会变为“高”。在这里,我们使用示波器来检测弹跳。而且,正如您在下面给出的波形中看到的那样,逻辑正在以轻微的曲线移动而不是弹跳。电路中使用的电阻是上拉电阻。
每当开关在触点之间移动以产生反弹时,触发器都会保持输出,因为“0”是从与非门的输出反馈的。
R-C 去抖
R-C 仅由其名称定义,该电路使用 RC 网络来防止开关弹跳。电路中的电容器滤除开关信号的瞬间变化。当开关处于打开状态时,电容器两端的电压保持为零。最初,当开关打开时,电容器通过 R1 和 R2 电阻器充电。
当开关闭合时,电容器开始放电至零,因此反相施密特触发器输入端的电压为零,因此输出变为高电平。
在弹跳情况下,电容器停止 Vin 处的电压,直到它达到 Vcc 或接地。
为了提高 RC 去抖动的速度,我们可以连接一个二极管,如下图所示。因此,它减少了电容器的充电时间。
开关去抖IC
市场上有用于开关去抖动的 IC。一些去抖 IC 是 MAX6816、MC14490 和 LS118。
下面是使用MAX6818进行开关去抖的电路图。
所以在这里,我们学习了按钮如何产生开关反弹效应,以及如何通过使用硬件的方式来防止按键抖动。
软件消抖
我们都知道,并且也是我们使用最多的场合是通过软件实现按键消抖。
最简单的方式是增加延迟以消除软件去抖。添加延迟会强制控制器在特定时间段内停止,但在程序中添加延迟并不是一个好的选择,因为它会暂停程序并增加处理时间。最好的方法是在代码中使用中断来进行软件弹跳。
sbit KEY = P1^3;
///按键读取函数
uint8_t GetKey(void)
{if(KEY == 1){DelayMs(20); //延时消抖if(KEY == 1){return 1;}else {return 0;}}else {return 0;}
}
上面是最简单的软件延时方法,也可以通过多个按键组合增加相关软件滤波的方式进行按键判断,其实原理相似。
但是这种纯延时的实现方式太过暴力,在延时的时候一直占用cpu的资源,如果在延时的时候,有其他外部中断或者抢占事件,系统完全没有响应的。
所以我们CPU需要一个独立的定时装置,来完成这个计时工作,而且需要在计时时间到达时再检测一次按键的电平值。
中断消抖
首先初始化管脚,打开管脚的外部中断:
/*Configure GPIO pins : KEY_1_Pin KEY_2_Pin */GPIO_InitStruct.Pin = KEY_1_Pin|KEY_2_Pin;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
static void MX_TIM1_Init(void)
{htim1.Instance = TIM1;htim1.Init.Prescaler = 7200 - 1; // 72000000 / 7200 = 10000 hz 0.01mshtim1.Init.CounterMode = TIM_COUNTERMODE_UP;htim1.Init.Period = 200 - 1; // 200 * 0.01 = 20mshtim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter = 0;htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim1) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{ if(htim_base->Instance==TIM1) {/* Peripheral clock enable */ __HAL_RCC_TIM1_CLK_ENABLE(); /* USER CODE BEGIN TIM1_MspInit 1 */HAL_NVIC_SetPriority(TIM1_UP_IRQn,1,3); HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); }
}
在stm32f1xx_hal_it.c中去注册中断回调函数(关键的步骤,需要在按键中断处理函数中打开定时器,开始计时):
void EXTI15_10_IRQHandler(void) // 按键的中断处理函数
{HAL_TIM_Base_Start_IT(&htim1); // 开启定时器1,开始计时printf("key down\r\n");__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_11);__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);
}
void TIM1_UP_IRQHandler(void)
{HAL_TIM_IRQHandler(&htim1); //这个是所有定时器处理回调的入口,在这个函数里对应定时器多种中断情况的中断回调,需要找到update的回调函数printf("TIM IRQ\r\n");}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) // 定时器update中断处理回调函数
{/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM2) {HAL_IncTick();}if (htim->Instance == TIM1) { // 在这里选择tim1 printf("TIM1 updata\r\n");HAL_TIM_Base_Stop_IT(&htim1); // 关闭tim1 及清除中断if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_11) ) //再次判断管脚的电平{printf("KEY1 be pressed!!!\r\n");}if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_12) )//再次判断管脚的电平{printf("KEY2 be pressed!!!\r\n");}}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}
总结一下,实现用定时器中断来完成按键延时去抖的关键步骤:
-
初始化GPIO脚,初始化TIM ,算好时间,填入分频值。
-
打开GPIO中断,在中断处理函数中打开定时器,让其计数。
-
定时器溢出中断函数中,再次判断按键电平值。关闭定时器,清除pending。
相关文章:

单片机按键消抖常用的软硬件方法
一:什么是开关抖动? 当我们按下按钮或拨动开关或微动开关时,两个金属部件会接触以短路电源。但它们不会立即连接,而是金属部件在实际稳定连接之前连接和断开几次。释放按钮时也会发生同样的事情。这会导致误触发或多次触发&#…...
钉钉自建应用-下载excel(h5)
由于不同手机对于文件下载有不同的支持,而且文件路径也不一样,找起来十分的麻烦。所以,最好是找到一个都支持的方法。还好,钉钉官网提供了网盘,我们可把文件保存到钉钉自带的网盘,这样方便查找。 这里需要…...

用二八定律分析零售数据,不就更直观了吗?
20%的商品贡献了80%的销售金额,你会不会想知道这些商品的销售金额、毛利、销售金额累计占比、毛利累计占比,会不会想知道这些商品在各个门店的销售表现?看是否能进一步提高销售金额,提高毛利。这样的报表该怎么做?奥威…...

NetSuite Saved Search-当前库存快照查询报表(二)
之前第一篇文章我们说明了,如何利用Saved Search来制作一个能够显示批次物料与非批次物料的Lot信息以及On Hand在手数量的“当前库存快照查询报表”,但是当用户提出“我们能否再加上批次物料的效期”需求时,我们原有的Saved Search并不能达到…...

【JavaSE】接口 详解(上)
前言 本篇会讲到Java中接口内容,概念和注意点可能比较多,需要耐心多看几遍,我尽可能的使用经典的例子帮助大家理解~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 接口 语法…...

嵌入式C基础——循环队列 ringbuffer 讲解
本期主题: 讲解ARRAY_SIZE的作用以及定义,还有一个踩坑分析 往期链接: 数据结构系列——先进先出队列queue数据结构系列——栈 stackLinux内核链表零长度数组的使用inline的作用嵌入式C基础——ARRAY_SIZE使用以及踩坑分析 目录 1. Ringbuff…...

【动态规划-状态压缩dp】【蓝桥杯备考训练】:毕业旅行问题、蒙德里安的梦想、最短Hamilton路径、国际象棋、小国王【已更新完成】
目录 1、毕业旅行问题(今日头条2019笔试题) 2、蒙德里安的梦想(算法竞赛进阶指南) 3、最短Hamilton路径(《算法竞赛进阶指南》&模板) 4、国际象棋(第十二届蓝桥杯省赛第二场C A组/B组&#…...

全坚固笔记本丨工业笔记本丨三防笔记本相较于普通笔记本有哪些优势?
三防笔记本和普通笔记本在设计和性能方面存在显著差异,三防笔记本相较于普通笔记本具备以下优势: 三防笔记本通常采用耐磨、耐摔的材料,并具有坚固的外壳设计,能够承受恶劣环境和意外碰撞,有效保护内部组件不受损坏。相…...
机房搬迁方案
一、项目背景 随着XX公司业务的不断扩展,现有的机房设备已经无法满足日益增长的数据处理需求。同时,考虑到现有机房的设施老化及潜在的安全隐患,XX公司决定进行机房搬迁。本次搬迁旨在确保业务连续性、数据安全性以及新机房的高效运营。 二…...

推动科技创新润德生物邀您到场参观2024第13届生物发酵展
参展企业介绍 山东润德生物科技有限公司成立于2014年10月17日,是一家围绕生物制品的研发、生产、营销、国际贸易、技术服务为核心业务的国家高新技术企业,近年来荣获国家制造业单项冠军示范企业、国家级绿色工厂、国家知识产权优势企业、国家工业产品绿…...
如何在JavaScript中提高性能
在JavaScript中提高性能是一个涉及多个方面的任务,包括代码优化、数据结构选择、异步编程、避免全局查找、内存管理等。以下是一些关键的策略和技巧,可以帮助你提高JavaScript代码的性能: 1. 优化循环 使用for循环代替forEach,特…...
外观模式(面子模式)
外观模式 文章目录 外观模式什么是外观模式示例 什么是外观模式 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 Facade 外观类 知道哪些子系统类负责处理请求,将客…...

蓝桥杯考前复习三
1.约数个数 由乘法原理可以得出: import java.util.*; public class Main{static int mod (int)1e9 7;public static void main(String[] args){Map<Integer,Integer> map new HashMap<>(); //创建一个哈希表Scanner scan new Scanner(System.in);i…...

极客时间: 用 Word2Vec, LangChain, Gemma 模拟全本地检索增强生成(RAG)
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
VBA操作Word
检查word中的字体情况 Sub ListAllFontsInDocument()Dim doc As DocumentDim rng As RangeDim char As RangeDim fontName As StringDim uniqueFonts As Collection 初始化集合用于存储唯一字体名称Set uniqueFonts New Collection 获取当前活动文档Set doc ActiveDocument …...

Linux文件IO(4):目录操作和文件属性获取
目录 1. 前言 2. 函数介绍 2.1 访问目录 – opendir 2.2 访问目录 – readdir 2.3 访问目录 – closedir 2.4 修改文件访问权限 – chmod/fchmod 2.5 获取文件属性 – stat/lstat/fstat 2.5.1 文件属性 – struct stat 2.6 文件类型 – st_mode 3. 代码练习 3.1 要求 3.2 代…...

【C语言】_文件类型,结束判定与文件缓冲区
目录 1. 文本文件和二进制文件 2. 文件读取结束的判定 3. 文件缓冲区 1. 文本文件和二进制文件 根据数据的组织形式,数据文件被称为文本文件或二进制文件; 数据在内存中以二进制的形式存储,如果不加转换地输出到外存,就是二进…...

YOLOV8注意力改进方法:DoubleAttention(附代码)
原论文地址:原论文地址 DoubleAttention网络结构的优点在于,它能够有效地捕获图像中不同位置和不同特征的重要性,从而提高了图像识别和分割的性能。 论文相关内容介绍: 论文摘要:学习捕捉远程关系是图像/视频识别的…...
每日一题 --- 前 K 个高频元素[力扣][Go]
前 K 个高频元素 题目:347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: …...

Rust所有权和Move关键字使用和含义讲解,以及Arc和Mutex使用
Rust 所有权规则 一个值只能被一个变量所拥有,这个变量被称为所有者。 一个值同一时刻只能有一个所有者,也就是说不能有两个变量拥有相同的值。所以对应变量赋值、参数传递、函数返回等行为,旧的所有者会把值的所有权转移给新的所有者&#…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...