按键FIFO——安富莱大佬的代码
1. 可靠地记录每一个按键事件,避免遗漏按键事件。特别是需要实现按键的按下、长按、自动连发、弹起等事件时。
2. 读取按键的函数可以设计为非阻塞的,不需要等待按键抖动滤波处理完毕。
3. 按键FIFO程序在嘀嗒定时器中定期的执行检测,不需要在主程序中一直做检测,这样可以有效地降低系统资源消耗。
typedef struct
{
下面是一个函数指针,指向判断按键手否按下的函数
uint8_t (*IsKeyDownFunc)(void); 按键按下的判断函数,1表示按下
uint8_t Count; 滤波器计数器
uint16_t LongCount; 长按计数器
uint16_t LongTime; 按键按下持续时间, 0表示不检测长按
uint8_t State; 按键当前状态(按下还是弹起)
uint8_t RepeatSpeed; 连续按键周期
uint8_t RepeatCount; 连续按键计数器
}KEY_T;bsp_DetectKey这个函数key.c检测的核心

typedef struct
{
下面是一个函数指针,指向判断按键手否按下的函数
uint8_t (*IsKeyDownFunc)(void); 按键按下的判断函数,1表示按下
uint8_t Count; 滤波器计数器
uint16_t LongCount; 长按计数器
uint16_t LongTime; 按键按下持续时间, 0表示不检测长按
uint8_t State; 按键当前状态(按下还是弹起)
uint8_t RepeatSpeed; 连续按键周期
uint8_t RepeatCount; 连续按键计数器
}KEY_T;主要就是对这个结构体的进行解算,bsp_KeyScan()函数里面不断进行扫描,bsp_KeyScan()主要是放在bsp_RunPer10ms(),然后丢到SysTick_Handler中10ms的扫描一次.
在bsp_DetectKey()函数里面直接调用外部结果提s_tBtn,然后进行数值的改变。
有两个初始化,一个是对结构体的值进行默认初始化,还有一个就是硬件的初始化,和我们普通的硬件端口初始化是一样的。
/* 对按键FIFO读写指针清零 */
s_tKey.Read = 0;
s_tKey.Write = 0;
s_tKey.Read2 = 0;
软件初始化需要拿出来单独说一下,初始化里面首先将FIFO缓冲设置初始值.
文件定义了一个结构体数组static KEY_T s_tBtn[KEY_COUNT],KEY_COUNT是按键的数量,而且这个数值是放在本文件中使用的,外部是无法调用的,真正读取键值的方式就是s_tBtn[0].IsKeyDownFunc = IsKeyDown1;
KEY_COUNT是按键的序号
typedef struct
{
uint8_t Buf[KEY_FIFO_SIZE]; /* 键值缓冲区 */
uint8_t Read; /* 缓冲区读指针1 */
uint8_t Write; /* 缓冲区写指针 */
uint8_t Read2; /* 缓冲区读指针2 */
}KEY_FIFO_T;
static KEY_FIFO_T s_tKey; /* 按键FIFO变量,结构体 */
//bsp_PutKey(); 将一个键值压入按键FIFO.用来模拟一个按键
void bsp_PutKey(uint8_t _KeyCode)
{
s_tKey.Buf[s_tKey.Write] = _KeyCode;
if (++s_tKey.Write >= KEY_FIFO_SIZE)
{
s_tKey.Write = 0;
}
}
//bsp_GetKey(); 从FIFO缓冲区中读取一个键值.
uint8_t bsp_GetKey(void)
{
uint8_t ret;
if (s_tKey.Read == s_tKey.Write)
{
return KEY_NONE;
}
else
{
ret = s_tKey.Buf[s_tKey.Read];
if (++s_tKey.Read >= KEY_FIFO_SIZE)
{
s_tKey.Read = 0;
}
return ret;
}
}相关推荐
安富莱开发板按键驱动
安富来按键驱动。能够识别短,长按,单击双击等不同的类型以及按键的组合。采用消息队列的方式。
单片机按键FIFO
本文代码参考安富莱按键FIFO FIFO数据结构如果不清楚可以参考博文简单的FIFO 一般的单片机系统,按键作为人机交互工具是必不可少的,但是普通的按键需要消抖处理,极大的增加了程序开销,降低系统实时性。 安富莱的FIFO按键,无需延时处理消抖,可以记录按键按下、弹起、长按、组合按,并且移植起来也十分方便。之前在做一个项目时,用到一个矩阵键盘,移植了这个按键FIFO程序,用起来效果很不错。 主要流程就是开启一个10ms的定时器中断,在中断中扫描按键状态,并对按键状态进行分析消抖处理,如果按键动作,将按键
基于安富莱STM32-V5开发板进行HAL库的FreeRTOS学习.zip (本人专注嵌入式领域)
嵌入式优质项目,资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目。 本人单片机开发经验充足,深耕嵌入式领域,有任何使用问题欢迎随时与我联系,我会及时为你解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明,项目具体内容可查看下方的资源详情。 【附带帮助】: 若还需要嵌入式物联网单片机相关领域开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步。 【本人专注嵌入式领域】: 有任何使用问题欢迎随时与我联系,我会及时解答,第一时间为你提供帮助,CSDN博客端可私信,为你解惑,欢迎交流。 【建议小白】: 在所有嵌入式开发中硬件部分若不会画PCB/电路,可选择根据引脚定义将其代替为面包板+杜邦线+外设模块的方式,只需轻松简单连线,下载源码烧录进去便可轻松复刻出一样的项目 【适合场景】: 相关项目设计中,皆可应用在项目开发、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面中 可借鉴此优质项目实现复刻,也可以基于此项目进行扩展来开发出更多功能
STM32 按键FIFO的实现.rar
1、设计按键FIFO的优点 要介绍实现按键FIFO的优点,首先要了解FIFO的一些基本概念。FIFO即First In First Out,是一种先进先出的数据缓存方式,例如在超市购物之后我们会提着满满的购物车来到收银台排在结账队伍的最后等待付款,先排队的客户先付款离开,后面排队的只有等待前面付款离开才能进行付款。说白了FIFO就是这样一种先进先出机制,先存入的数据在读取时最先被读取到。 设计按键FIFO注意有三个方面的优点(来自于安富莱电子Eric2013大佬总结): 1、可以有效记录按键事件的发生,特别是系统要实现记录按键按下、松开、长按时,使用FIFO来实现是一种不错的选择方式。 2、系统是阻塞的,这样系统在检测到按键按下的情况,由于机械按键抖动的原因不需要在这里等待一段时间,然后在确定按键是否正常按下。 3、按键FIFO程序在系统定时器中定时检测按键状态,确认按键按下后将状态写入FIFO中,不一定在主程序中一直做检测,这样可以有效降低系统资源的消耗。 2、按键的硬件设计 按键的原理图如上图所示,对于KEY0~KEY2这三个按键,一端接地,另一端连接stm32的GPIO端口。当按键按下时相应的IO口被拉低,如果把GPIO口配置为输入模式,此时读取相应的IO口电平,就可以检测到按键是否被按下。对于KEY_UP按键则是与前面三个按键相反,IO口配置为输入模式时,读取到高电平时表示按键按下。因为机械固有的物理特性,按键按下内部弹簧片在瞬间接触的时候会有力学的回弹,造成2-8毫秒内信号不稳定,所以在设计检测机械按键是否按下的程序时,应考虑到按键消抖问题。
源码(资料):按键框架(20250506)
【B站@我是龙虾哥】 1.第9节:按键框架程序 2.视频:第9节(补充)_可能是B站最好的按键检测框架 【安富莱】 01.第10期BSP驱动教程:STM32H7的GPIO专题,非阻塞式驱动编程思想,按键FIFO,蜂鸣器驱动的新式玩法 02.[GPIO] 分享个STM32H7的按键单击,双击和长按的例子 【MultiButton】 1.GitHub@0x1abin_MultiButton 多按钮 (20250506)


单片机/工控
