51单片机自学--完美的单击、双击、长按、中断消抖

本文介绍了一种高效的按键处理方法,通过巧妙的设计实现单击、双击和长按的区分。该方法仅在按键按下时执行消抖延时,并利用此过程进行双击判断,代码简洁且易于理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完整的单击、双击、长按代码。

工作原理:当有按钮第一次按下时,设置第一个标志An,当按钮第一次释放后,进入中断消抖延时计数,假如在计数范围内第二次按钮按下,设置第二标志Aa,这样就把单击和双击区分开,而且是可靠的逻辑标志,长按为大于1秒的判断.

中断消抖及按钮单击、双击、长按处理,双击在仿真中稳稳地检测到执行。

之前发布的矩阵按键也一样可以采用中断延时,不过时间应该更短,如50-100毫秒。

本代码的巧妙之处在于:

1.只有按钮按下才执行消抖延时,否则不执行延时

2.巧妙利用消抖延时,同时检查按键双击判断

3.判断设计精巧,代码短小精悍

4.消抖延时时间极易调整

5.多极判断可扩展性良好

6.构思巧妙,易于理解其原理

中断是一个知识点也是需要谨慎处理的点,处理不好的话,运行起来会看到怪现象,简单的话当然不会看到什么影响,不过即使是简单的数码管显示还是按键消抖,我也觉得有必要研究如何是最优的在一个中断源中处理.

 

### STM32 按键中断实现方法 对于STM32单片机中的按键处理,采用外部中断触发的方式能够有效提高响应速度并减少CPU占用率。然而,机械按键在按下和释放瞬间会产生动现象,这可能导致多次触发中断事件。为了确保每次按键操作仅被识别一次,在硬件层面或软件层面上都需要采取措施来除这种干扰。 #### 软件策略 一种常见的做法是在检测到边沿变化时启动一个短暂的时间延迟(通常为几毫秒),在此期间忽略任何额外的状态改变直到确认信号已经稳定下来[^2]。具体而言: - 当首次捕捉到上升沿或下降沿时记录当前时刻; - 进入等待状态一段时间(比如20ms); - 如果在这段时间结束之后再次读取同一引脚仍然保持相同的逻辑电平,则认为是一次有效的按键动作;反之则视为噪声而丢弃掉此次中断请求。 这种方法不仅适用于简单的二态开关控制,而且还可以扩展应用于矩阵键盘扫描等复杂场景之中。值得注意的是,利用HAL库提供的`HAL_GetTick()`函数可以轻松获取系统滴答计数值来进行时间间隔判断。 #### 定时器辅助的高效方案 另一种更为优化的方法是结合定时器资源完成自动化的去流程。每当发生按键事件时重装载预设好的定时期限,并开启该定时通道;一旦超时未再收到新的触发脉冲即判定为真实输入。此过程完全基于硬件机制运作,几乎不耗处理器周期,从而提高了整体性能表现[^4]。 下面给出一段C语言代码片段作为示例说明如何运用上述原理编写可靠的按键服务程序: ```c #include "stm32f1xx_hal.h" #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_PORT GPIOA #define DEBOUNCE_TIME 20 // ms volatile uint8_t buttonPressedFlag = 0; uint32_t lastDebounceTime; void EXTI0_IRQHandler(void){ HAL_GPIO_EXTI_IRQHandler(BUTTON_PIN); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ if(GPIO_Pin == BUTTON_PIN){ uint32_t currentTime = HAL_GetTick(); // Ignore interrupts that occur too quickly after each other. if((currentTime - lastDebounceTime) > DEBOUNCE_TIME){ lastDebounceTime = currentTime; // Read the current state of the pin to ensure it's stable. if(HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN)){ buttonPressedFlag = 1; // Set flag indicating a valid press event occurred. } }else{ __NOP(); // Do nothing and wait until debounce period has passed. } } } ``` 这段代码实现了对外部中断源的有效管理以及合理的防处理逻辑。当检测到按键活动时更新全局变量`buttonPressedFlag`标志位通知主循环部分进一步处理用户交互行为。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值