硬汉嵌入式论坛

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

[GPIO] 分享个STM32H7的按键单击,双击和长按的例子

  [复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
发表于 2021-6-1 10:16:51 | 显示全部楼层 |阅读模式
经常有客户咨询双击支持,做个例子分享给大家,这个修改了bsp_key.c的驱动实现。
V7-单击,双击,长按(V1.1).7z (1.31MB)

image.png




回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2021-6-1 11:12:06 | 显示全部楼层
赞!!!!!!!!!!!!!!!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2021-6-2 10:39:09 | 显示全部楼层
282209507 发表于 2021-6-1 11:12
赞!!!!!!!!!!!!!!!

造福全人类。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2021-12-27 11:06:42 | 显示全部楼层
dddddddddddddd
回复

使用道具 举报

5

主题

144

回帖

159

积分

初级会员

积分
159
发表于 2021-12-27 11:41:19 | 显示全部楼层
有个开源按键组件挺好用的  https://github.com/0x1abin/MultiButton
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2021-12-27 15:41:53 | 显示全部楼层

不用回复,直接就能下载。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2021-12-27 15:42:32 | 显示全部楼层
无关风月 发表于 2021-12-27 11:41
有个开源按键组件挺好用的  https://github.com/0x1abin/MultiButton

谢谢分享,这里也有一个。

【按键检测-功能大全】基于硬汉程序思想-进行深度优化
https://www.armbbs.cn/forum.php? ... 6136&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-6-20 10:27:51 | 显示全部楼层
可以做个多击的实现么
回复

使用道具 举报

21

主题

66

回帖

129

积分

初级会员

积分
129
发表于 2022-6-20 20:05:56 | 显示全部楼层
我很多年前也写过一个全功能的按键程序,相对比较短小精悍

功能如下:
  支持最大64个按键(数量可配置)。
  支持按键消抖处理(可滤掉小于2个扫描周期的毛刺)。
  支持按键环形缓冲区(长度可配置)。
  支持4种不同按键模式:A:短按键 B:shift键 C:长按单发 D:长按连发。
  短按键 :短按直接输出键值。
  shift键 :点击后除了输出一次shift键的键值码外,还将后续所有其他按键的键值改为shift键值码
  长按连发 :长按一定时间后连续输出按键键值。
  长按单发 :长按一定时间后反码输出键值(仅一次)
  4种不同按键模式可相互叠加使用,所有按键功能都能并发输出。

https://github.com/mojinpan/key
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2022-9-29 14:42:28 | 显示全部楼层
代码里面的 bsp_GetKey2 好像没什么用吧,这个是不是冗余的代码,或者是有什么特殊用途上的考虑?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2022-9-29 16:14:51 | 显示全部楼层
maoxia007 发表于 2022-9-29 14:42
代码里面的 bsp_GetKey2 好像没什么用吧,这个是不是冗余的代码,或者是有什么特殊用途上的考虑?

这个没用,可以删掉。
回复

使用道具 举报

11

主题

30

回帖

63

积分

初级会员

积分
63
发表于 2022-10-28 17:38:29 | 显示全部楼层
s_tBtn[i].LongTime = KEY_LONG_TIME;                        /* 长按时间 0 表示不检测长按键事件 */
                s_tBtn[i].Count = KEY_FILTER_TIME / 2;                /* 计数器设置为滤波时间的一半 */

这里为什么要设置成滤波时间一半啊
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2022-10-29 00:40:06 | 显示全部楼层
小韩同学 发表于 2022-10-28 17:38
s_tBtn.LongTime = KEY_LONG_TIME;                        /* 长按时间 0 表示不检测长按键事件 */
                s_tBtn.Count = KEY_FILTE ...

设置了个初始值,没有特别含义
image.png


回复

使用道具 举报

32

主题

110

回帖

206

积分

高级会员

积分
206
发表于 2023-5-18 10:53:03 来自手机 | 显示全部楼层
请问有没有矩阵键盘的单机,双击,长按的例子呢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2023-5-18 10:53:40 | 显示全部楼层
伊森亨特 发表于 2023-5-18 10:53
请问有没有矩阵键盘的单机,双击,长按的例子呢

矩阵键盘的没做。
回复

使用道具 举报

32

主题

110

回帖

206

积分

高级会员

积分
206
发表于 2023-11-7 08:58:54 | 显示全部楼层
这个是长按执行一次,还是长按连发
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2023-11-7 11:34:10 | 显示全部楼层
伊森亨特 发表于 2023-11-7 08:58
这个是长按执行一次,还是长按连发

默认没有开连发,连发需要手动使能。
回复

使用道具 举报

2

主题

15

回帖

21

积分

新手上路

积分
21
发表于 2024-5-21 17:00:03 | 显示全部楼层
我移植后 设置双击 无效啊 一直都是按键按下按键弹起  触发不了这个双击事件
回复

使用道具 举报

2

主题

15

回帖

21

积分

新手上路

积分
21
发表于 2024-5-22 09:23:39 | 显示全部楼层
硬汉哥 我移植你的代码跑不起来呀
真难受
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2024-5-22 13:00:50 | 显示全部楼层
ask张 发表于 2024-5-22 09:23
硬汉哥 我移植你的代码跑不起来呀
真难受

方便的话,分享你的工程代码到百度云
回复

使用道具 举报

2

主题

15

回帖

21

积分

新手上路

积分
21
发表于 2024-5-22 14:34:07 | 显示全部楼层
好的 哥 晚点我发给你看看 谢谢了
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2024-8-16 11:57:17 | 显示全部楼层
老哥真厉害,已经移植STC单片机成功,就是不太懂       if (key->repeat_speed > 0)
                    {
                        if (++key->repeat_count >= key->repeat_speed)
                        {
                            key->repeat_count = 0;
                            /* 常按键后,每隔10ms发送1个按键弹起事件 */
                            //Put_Key((uint8_t)(4 * i + 1));  这是发按键按下事件
                            Put_Key((uint8_t)(KEY_MSG_STEP * i + KEY_1_AUTO_UP));
                        }
                    }这里面KEY_1_AUTO_UP和repeat_count 的关系,KEY_1_AUTO_UP这东西怎么理解呢
回复

使用道具 举报

5

主题

29

回帖

44

积分

新手上路

积分
44
QQ
发表于 2024-8-16 16:53:36 | 显示全部楼层
代码(bsp.key.h)里头的定义的每一个按键的这个状态   “KEY_1_AUTO_UP,              /* 1键长按后自动发码 */”的目的不懂:什么叫长按后自动发码?
每一个键有:
a. 短按(对应两个状态:DOWN 和 UP);
b.长按(对应两个状态:DOWN 和 UP);
c. 双击,是不是也是两个状态, KEY_1_DB_UP, 这个确定,“KEY_1_AUTO_UP”这个怎么解释,没有想明白?麻烦懂得解释一下?
回复

使用道具 举报

5

主题

29

回帖

44

积分

新手上路

积分
44
QQ
发表于 2024-8-16 16:54:42 | 显示全部楼层
代码(bsp.key.h)里头的定义的每一个按键的这个状态   “KEY_1_AUTO_UP,              /* 1键长按后自动发码 */”的目的不懂:什么叫长按后自动发码?
每一个键有:
a. 短按(对应两个状态:DOWN 和 UP);
b.长按(对应两个状态:DOWN 和 UP);
c. 双击,是不是也是两个状态, KEY_1_DB_UP, 这个确定,“KEY_1_AUTO_UP”这个怎么解释,没有想明白?麻烦懂得解释一下?
回复

使用道具 举报

5

主题

29

回帖

44

积分

新手上路

积分
44
QQ
发表于 2024-8-16 17:12:10 | 显示全部楼层
状态:KEY_1_AUTO_UP、变量 repeat_count、repeat_speed,也是不太明白,谁能说说吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2024-8-17 10:22:47 | 显示全部楼层
aa520520 发表于 2024-8-16 11:57
老哥真厉害,已经移植STC单片机成功,就是不太懂       if (key->repeat_speed > 0)
                     ...

这个是长按后,继续按下去的连发支持,类似你按下电脑键盘一个字母键,一直按下去会连续发送这个字母
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2024-8-17 10:23:11 | 显示全部楼层
hongqi1O29 发表于 2024-8-16 16:54
代码(bsp.key.h)里头的定义的每一个按键的这个状态   “KEY_1_AUTO_UP,              /* 1键长按后自动发码 */”的 ...

这个是长按后,继续按下去的连发支持,类似你按下电脑键盘一个字母键,一直按下去会连续发送这个字母
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2024-8-28 13:10:26 | 显示全部楼层
eric2013 发表于 2024-8-17 10:22
这个是长按后,继续按下去的连发支持,类似你按下电脑键盘一个字母键,一直按下去会连续发送这个字母

谢谢老哥
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2024-12-11 14:53:15 | 显示全部楼层
eric2013 发表于 2024-8-17 10:22
这个是长按后,继续按下去的连发支持,类似你按下电脑键盘一个字母键,一直按下去会连续发送这个字母

请问一下,systick 软件定时器中,开关中断,如果我有使用串口接收中断,然后软件定时器中开关中断会不会影响串口啊
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2024-12-12 09:37:40 | 显示全部楼层
aa520520 发表于 2024-12-11 14:53
请问一下,systick 软件定时器中,开关中断,如果我有使用串口接收中断,然后软件定时器中开关中断会不会 ...

是指的在check timer的判断函数里面做开关中断把,开关时间短的话不影响。

另外你开关中断可以考虑仅开关有影响的中断,不要开关全局中断在,这样就不影响串口中断了
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2024-12-12 10:52:25 | 显示全部楼层
eric2013 发表于 2024-12-12 09:37
是指的在check timer的判断函数里面做开关中断把,开关时间短的话不影响。

另外你开关中断可以考虑仅 ...

好的谢谢,昨晚改成关闭systick中断了
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2025-1-9 11:07:48 | 显示全部楼层
*/
static uint8_t IsKeyDownFunc(uint8_t _id)
{
        /* 实体单键 */
        if (_id < HARD_KEY_NUM)
        {
                uint8_t i;
                uint8_t count = 0;
                uint8_t save = 255;
               
                /* 判断有几个键按下 */
                for (i = 0; i < HARD_KEY_NUM; i++)
                {
                        if (KeyPinActive(i))
                        {
                                count++;
                                save = i;
                        }
                }
               
                if (count == 1 && save == _id)
                {
                        return 1;        /* 只有1个键按下时才有效 */
                }               

                return 0;
        }
        老板,现在发现一个问题,如果我K1一直按下的过程中,如果此时我按一下K2,在这个函数里面,会让count = 2,然后返回0,导致再发送K1 弹起事件,
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2025-1-9 11:11:22 | 显示全部楼层
static uint8_t IsKeyDownFunc(uint8_t _id)
{
        /* 实体单键 */
        if (_id < HARD_KEY_NUM)
        {
                uint8_t i;
                uint8_t count = 0;
                uint8_t save = 255;
               
                /* 判断有几个键按下 */
                for (i = 0; i < HARD_KEY_NUM; i++)
                {
                        if (KeyPinActive(i))
                        {
                                count++;
                                save = i;
                        }
                }
               
                if (count == 1 && save == _id)
                {
                        return 1;        /* 只有1个键按下时才有效 */
                }               

                return 0;
        }老板,如果K1一直保持按下,然后此时按下K2,会让count =2 ,而return 0,而发送K1弹起事件,这个应该咋办啊
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115518
QQ
 楼主| 发表于 2025-1-10 07:20:54 | 显示全部楼层
aa520520 发表于 2025-1-9 11:07
*/
static uint8_t IsKeyDownFunc(uint8_t _id)
{

当前的这个驱动方式,不支持依次按下。

可以参考坛友这个改进下

【按键检测-功能大全】基于硬汉程序思想-进行深度优化
https://www.armbbs.cn/forum.php? ... 6136&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

8

回帖

8

积分

新手上路

积分
8
发表于 2025-1-14 10:20:53 | 显示全部楼层
eric2013 发表于 2025-1-10 07:20
当前的这个驱动方式,不支持依次按下。

可以参考坛友这个改进下

好的谢老板
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-29 16:29 , Processed in 0.483159 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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