在嵌入式系统开发领域,STM32微控制器以其高性能、灵活性和丰富的功能而广受欢迎,特别是STM32F103系列。在用户交互设计中,按键是最基本的输入设备之一,而如何高效准确地处理按键事件,包括消抖、单击、双击、三击和长按,是软件开发的关键点。状态机作为一种描述系统行为的设计模式,特别适合处理这类输入事件。 状态机的实现方式很多,本文将探讨如何使用STM32的HAL(硬件抽象层)库来实现一个状态机,以处理按键的不同操作状态。按键消抖是一个必须解决的问题。在实际电路中,按键由于机械特性,在接触时会产生抖动,这会在电气上造成多次触发。通过软件消抖,即在检测到按键状态改变后,延时一小段时间(比如50ms),再次确认按键状态,从而确保检测到的状态是稳定的。 接下来,单击、双击、三击和长按的区分需要对按键的时间间隔进行精确的计时。这通常涉及到定时器中断的使用。通过设置定时器中断,在一定时间间隔内检测按键状态,可以准确判断用户操作。例如,如果检测到按键被按下后,在预定时间内没有再次检测到按键动作,则认为是单击事件;如果在第二个预定时间内检测到按键再次被按下,则认为是双击事件;同样地,三次按键动作则对应为三击事件。长按事件则通常是检测到按键持续被按下的时间超过某个阈值。 在STM32F103的HAL库中,定时器和中断的配置相对简单。需要初始化定时器,设置合适的时钟源和预分频值,从而得到需要的中断触发频率。然后,在中断服务函数中实现按键状态的检查逻辑,根据按键状态的持续时间来触发相应的事件处理函数。 此外,在实现时还要考虑系统的响应效率和实时性。例如,为了避免单击事件被误判为长按,应确保在检测到长按之前,单击事件的逻辑已经处理完毕;同时,避免在处理长按逻辑时,错过对单击和双击的检测。 在代码实现上,状态机的主体结构需要定义多个状态,如等待按键按下、等待单击确认、等待第二次按下、等待第三次按下、长按处理等。每个状态对应一个处理函数,用于执行该状态下应有的逻辑。状态转换的触发条件基于按键事件和定时器中断的返回结果。 根据实际应用需求,还可能需要对状态机进行优化,比如引入防抖时间和多级按键响应逻辑,以提高系统的稳定性和用户体验。通过合理设计状态机和利用STM32F103的HAL库,可以有效地处理各种按键事件,并在嵌入式系统中实现复杂的用户交互逻辑。
2025-06-13 11:20:37 705KB STM32
1
基于HAL库,状态机编程STM32F103单片机实现按键消抖,处理按键单击,双击,三击,长按事件。开启定时器中断处理
2024-07-25 22:25:48 437KB stm32 编程语言 按键消抖
1
应广是采用自己的IDE进行变成,并且采用的是mini-c的编程语言,这种语言介于汇编和c之间,学习起来有点云里雾里,但是好处也很多,软件内集成了很多现成的编程,只需要稍加修改就可以啦。 但缺点也较为明显,网上的教程和资料真的超级少,而且比较低端!!!
2023-03-24 23:53:59 38KB 单片机 嵌入式
1
原创代码:单按键实现:单击、双击、多击、长按等功能,代码设计巧妙,通俗易懂,考虑去按键抖动,lua代码
2022-11-22 17:44:33 866B 单按键多功能
1
RecyclerView基类的封装(单击双击事件)及附demo完整使用操作
2022-10-20 21:10:01 3KB RecyclerView
1
ESP32最小系统板上只有一个按键,实验中为了实现更加丰富的功能,同时提供按键处理的实时性要求,特别写了一个CLASS,实现类似于鼠标单击、双击、三连击、长按等功能,模块化设计,加了详细中文说明,可读性强,可移植性强。
2022-10-03 21:35:22 2KB stm32 arm 嵌入式硬件 单片机
1
#include "ioCC2530.h" #define LED1 P1_0 #define LED2 P1_1 #define JD1 P1_7//继电器1 #define JD2 P2_0//继电器第二联 #define SW1 P1_2//按键1 unsigned char count=0; unsigned char Num=0; void delay(int time) { while(time--) { for(int i=0;i<240;i++); } } void Init_Port() { P1SEL &=~ 0x9f;//设置P1口的通用输入输出端口 P1DIR |=0x9b; P1DIR &=~0x04; P1INP &=~0x04;//设置输入模式 P2INP &=~0x40; P2SEL &=~0x01;//设置P2口的通用输入输出端口 P2DIR |=0x01; } void Timer_Init() { T1CC0L =0xD4; T1CC0H = 0x30; T1CCTL0 |=0x04; T1IE=1; EA=1; T1CTL =0x0e; } #pragma vector=T1_VECTOR __interrupt void Timer1_int() { T1STAT &=~0x20; if(SW1 !=0 && Num !=0) { count++; } } void Scan() { if(SW1==0) { delay(100); if(SW1==0) { while(SW1==0); count=0; Num++; if(Num>2) { Num=2; } } } if(count>5) { if(Num==1) { JD1 =!JD1;//继电器1 的状态改变 LED2=1; LED1=0; } else if(Num==2) { JD2=!JD2;//继电器2的状态改变 LED1=1; LED2=0; } count=0; Num=0; } } void main(void) { Init_Port(); Timer_Init(); LED1=1; LED2=1; JD1=0; JD2 =0; while(1) { Scan(); } }
2022-08-02 10:47:47 1KB CC253 单击双 双联继电 SW
1
个人博客:CSDN “老子姓李!” 参考教程链接:http://t.csdn.cn/W9rIy 引言: 在日常生活中,有不少按键长按、短按的应用实例。比如:一个台灯,短按切换亮度,长按关机。 问题来了,单片机是如何区分按键的短按和长按的呢? 本程序使用定时器,运用状态机的思想,实现了单按键的单击长按操作。 代码简洁规范,可读性强,移植性强。 实验器材: 自制开发板,STM32F03C8T6平台 实验目的: 学习定时器中断、按键使用。实现单击双击长按操作 硬件资源: 按键(PA0,也称之为WK_UP) 定时器3 串口1,用于打印输出 按键事件: 长按事件:任何大于 1秒 按下并释放事件(不支持连按,需连按,稍微修改状态机即可) 单击事件:按下时间不超过 1秒 且 释放后 500ms 内无再次按下的操作 双击事件:俩次短按时间间隔小于500ms,俩次短按操 本程序只供学习使用,未经作者许可,不得用于其它任何用途 感谢大家的阅读与下载,码字开源分享不易,麻烦给个免费的赞。 如果有帮助的,请不要吝啬三连。点赞评论收藏,让更多人看到有用的内容。 本博客作抛砖引玉,欢迎大家评论交流。
2022-06-02 20:01:03 182KB stm32 嵌入式硬件 单片机 状态机
1
android view 单击、双击和移动事件处理
2022-05-17 17:38:50 990KB android view 事件处理
1
一个按键扫描的程序很经典,有单击 双击 还有长按 都可以自己设置时间参数,而且双击的时候不会出发单击,里面的算法思想很经典,我经常使用可以拿来学习一下··
2022-05-04 00:52:23 2KB 按键 双击 长按 单片机
1