硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1624|回复: 7
收起左侧

[STM32H7] 按键功能 优化

[复制链接]

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2024-4-9 23:48:40 | 显示全部楼层 |阅读模式
按键代码优化,主要有以下几点:
1. 统一按键编码,单个按键以及组合按键
[C] 纯文本查看 复制代码
typedef enum
{
	KeyID_None = 0,
	KeyID_SingKey_Begin = KeyID_None,
	KeyID_K1,
	KeyID_K2,
	KeyID_K3,
	KeyID_JOY_U,
	KeyID_JOY_D,
	KeyID_JOY_L,
	KeyID_JOY_R,
	KeyID_JOY_OK,
	KeyID_SingKey_End,
	KeyID_CombKey_Begin,
	KeyID_Comb_K13,
	KeyID_Comb_K23,
	KeyID_CombKey_End
} key_id_e;


使用 额外的枚举值生成宏变量, 为 bsp_key.c 文件提供按键数目信息
[C] 纯文本查看 复制代码
#define KEY_SINGLE_NUM  (KeyID_SingKey_End - KeyID_SingKey_Begin - 1)
#define KEY_COMB_NUM    (KeyID_CombKey_End - KeyID_CombKey_Begin - 1)
#define KEY_TOTAL_NUM   (KEY_SINGLE_NUM + KEY_COMB_NUM)


2. 使用函数指针,屏蔽底层
1 和 2 确保了 bsp_key.c 和具体设备无关, 不同开发板代码移植时,只需要修改 bsp_key.h 的枚举类型 key_id_e 以及 bsp_key_ll.c 文件,后者提供了底层实现
3. 尽可能将结构体放在  bsp_key.c 文件,
4. 按键缓冲中每个buffer 存放 uint8_t 类型,该类型包含按键 ID 和 按键状态信息
[C] 纯文本查看 复制代码
#define GET_KEY_CODE(id, status)  (uint8_t)(((uint8_t)status << 5) + ((uint8_t)id & 0x1F))
#define GET_KEY_ID(code)          (key_id_e)(code & 0x1F)
#define GET_KEY_STATE(code)       (key_state_e)(code >> 5)


5. 待优化:
bsp_KeyScan10ms 不需要暴露出来,而是在 bsp_InitKey 将函数注册到 定时扫描函数数组,
按键状态也支持函数注册,当某个按键状态发生时,调用之前注册的函数。


细节都在代码中,就4个文件不同,bsp_key.c, bsp_key.h, bsp_key_ll.c 以及 bsp_key_ll.h

1_Key.zip

2.88 MB, 下载次数: 26

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2024-4-10 09:54:06 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

4

主题

412

回帖

424

积分

高级会员

积分
424
发表于 2024-4-10 20:52:15 | 显示全部楼层
不考虑0x1abin/MultiButton的么,防抖更强哦
#define DEBOUNCE_TICKS    3        //MAX 7 (0 ~ 7)

[C] 纯文本查看 复制代码

/*------------button debounce handle---------------*/
	if(read_gpio_level != handle->button_level) { //not equal to prev one
		//continue read 3 times same new level change
		if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) {
			handle->button_level = read_gpio_level;
			handle->debounce_cnt = 0;
		}
	} else { //level not change ,counter reset.
		handle->debounce_cnt = 0;
	}


回复

使用道具 举报

5

主题

19

回帖

34

积分

新手上路

积分
34
发表于 2024-5-31 12:00:09 | 显示全部楼层
cctv180 发表于 2024-4-10 20:52
不考虑0x1abin/MultiButton的么,防抖更强哦
#define DEBOUNCE_TICKS    3        //MAX 7 (0 ~ 7)

看你分享的MultiButton,是通过回调函数来直接触发按键事件的,也就是在5ms的tick中断中直接执行的;
而H7例程是通过FIFO先存储按键事件,然后再通过轮询FIFO内容来执行按键事件的;
这两种方式应该如何做取舍呢?
回复

使用道具 举报

25

主题

233

回帖

308

积分

高级会员

积分
308
QQ
发表于 2024-5-31 20:00:28 | 显示全部楼层
叮个隆咚呛 发表于 2024-5-31 12:00
看你分享的MultiButton,是通过回调函数来直接触发按键事件的,也就是在5ms的tick中断中直接执行的;
而 ...

仅讨论"事件立即执行"和"事件入fifo被消费"。
时间维度我觉得是没有高下的,这是用户交互系统的部分,时间不敏感,早晚执行几十毫秒用户感受不明显。
功能维度我认为是fifo模式更出众,在有按键事件优先级或者先后顺序的情况下,也可以进行嵌入式地拓展。

如果说事件的产生逻辑,MultiButton是强很多的,将按键抽象化,不再与GPIO强关联,在任何跟时间判定相关的应用场合,都可以抽象成按键。不太恰当的例子,例如某个错误位,为了避免误触发就可以抽象成按键,经过按键驱动消抖达成单次按下事件,则可以认为错误确实存在。

另做一个按键事件fifo,MultiButton的事件触发时进行入fifo操作,再对事件fifo系统进行拓展开发,我觉得这样是比较优秀的设计,各层应用的复用性都很强。

我拓展开发了一个MultiButton的fork,弥补了原版库的少量缺陷,略微增强了适用性,可供参考。
stbanana/MultiButton: Button driver for embedded system. Expand development based on existing projects. (github.com)
回复

使用道具 举报

5

主题

19

回帖

34

积分

新手上路

积分
34
发表于 2024-6-3 17:15:42 | 显示全部楼层
yono 发表于 2024-5-31 20:00
仅讨论"事件立即执行"和"事件入fifo被消费"。
时间维度我觉得是没有高下的,这是用户交互系统的部分,时 ...

好的,明白了。MultiButton和fifo结合一下,实时性和准确性会比较好。
回复

使用道具 举报

32

主题

115

回帖

211

积分

高级会员

积分
211
发表于 2024-7-15 14:28:50 | 显示全部楼层
yono 发表于 2024-5-31 20:00
仅讨论"事件立即执行"和"事件入fifo被消费"。
时间维度我觉得是没有高下的,这是用户交互系统的部分,时 ...

你好,请问你写的这个支持矩阵案件吗?谢谢
回复

使用道具 举报

25

主题

233

回帖

308

积分

高级会员

积分
308
QQ
发表于 2024-7-15 19:58:58 | 显示全部楼层
伊森亨特 发表于 2024-7-15 14:28
你好,请问你写的这个支持矩阵案件吗?谢谢

不是我写的嗷。这个是单按键驱动,主要用于电平消抖和事件回调,是硬件驱动层。单反是个硬件按键当然都需要这样的消抖和单按连按检测。
矩阵按键逻辑事实上是纯软件层了,你可以使用库的单按回调在外包装一层。
我也是这样干的,写数字键盘的驱动层,彻底与硬件解耦,不过不算规范,不可分享。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-15 02:14 , Processed in 0.043375 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表