前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MultiButton事件触发型按键驱动模块在高云FPGA上的移植

MultiButton事件触发型按键驱动模块在高云FPGA上的移植

原创
作者头像
单片机点灯小能手
修改2023-09-24 12:10:14
5182
修改2023-09-24 12:10:14
举报

前两篇文章介绍了letter-shell串口终端和cmd-parse串口命令解析器在高云FPGA GW1NSR-4C SoC上的移植:

本文介绍一个非常简单、功能强大的按键驱动模块MultiButton在高云FPGA上的移植。

1. MultiButton简介

MultiButton, 一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。

MultiButton 项目遵循MIT开源许可协议,允许使用者自由的分发和修改,许可证条件比较宽松,目前已经收获了1042个Star。

MultiButton 采用标准C语言开发,基于面向对象的设计思想,每个按键对象使用一个独立的数据结构进行管理。

支持多种按键触发方式:

  • PRESS_DOWN,按键按下,每次按下都触发
  • PRESS_UP,按键弹起,每次松开都触发
  • PRESS_REPEAT,重复按下触发,变量repeat计数连击次数
  • SINGLE_CLICK,单击按键事件
  • DOUBLE_CLICK,双击按键事件
  • LONG_PRESS_START,达到长按时间阈值时触发一次
  • LONG_PRESS_HOLD,长按期间一直触发

2. MultiButton代码获取

项目的GitHub地址:

代码语言:javascript
复制
https://github.com/0x1abin/MultiButton

如果国内访问不稳定,可以到GitCode镜像地址下载:

代码语言:javascript
复制
https://gitcode.net/mirrors/0x1abin/MultiButton

源代码下载到本地:

代码语言:javascript
复制
$ git clone https://gitcode.net/mirrors/0x1abin/MultiButton.git --depth=1
?
Cloning into 'MultiButton'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 2), reused 1 (delta 0), pack-reused 0
Receiving objects: 100% (9/9), 5.67 KiB | 5.67 MiB/s, done.
Resolving deltas: 100% (2/2), done.

整个项目非常小巧,只有两个文件:multi_button.c和multi_button.h

3. MultiButton移植

MultiButton的移植非常简单,只需要把multi_button.c和multi_button.h两个文件添加到工程,再实现一个按键状态读取函数,再通过5ms定时器调用处理函数就完成了移植,支持多种嵌入式平台。

首先,包含头文件,并定义一个按键:

代码语言:javascript
复制
#include "multi_button.h"
?
struct button btn1;

根据自己所使用的嵌入式平台,实现对按键状态的读取,我使用的是高云GW1NSR-4C FPGA SoC:

代码语言:javascript
复制
uint8_t read_button_GPIO(void)
{
    return GPIO_ReadBits(GPIO0) & 1;
}

再实现一个通用的按键回调函数,用于处理不同触发条件下的响应,这里为了演示,是打印对应的字符串:

代码语言:javascript
复制
void button_callback(void *button)
{
    PressEvent event = get_button_event((struct button *)button); 
    switch(event)
    {
        case PRESS_DOWN      : printf("PRESS_DOWN      \r\n"); break;
        case PRESS_UP        : printf("PRESS_UP        \r\n"); break;
        case PRESS_REPEAT    : printf("PRESS_REPEAT    \r\n"); break;
        case SINGLE_CLICK    : printf("SINGLE_CLICK    \r\n"); break;
        case DOUBLE_CLICK    : printf("DOUBLE_CLICK    \r\n"); break;
        case LONG_PRESS_START: printf("LONG_PRESS_START\r\n"); break;
        case LONG_PRESS_HOLD : printf("LONG_PRESS_HOLD \r\n"); break;
        default:
            break;
    }
}

初始化按键,并把按键触发事件和回调函数进行绑定:

代码语言:javascript
复制
button_init(&btn1, read_button_GPIO, 0);
button_attach(&btn1, PRESS_DOWN,       button_callback);    //按键按下触发一次
button_attach(&btn1, PRESS_UP,         button_callback);    //按键松开触发一次
button_attach(&btn1, SINGLE_CLICK,     button_callback);    //按键单击触发一次
button_attach(&btn1, DOUBLE_CLICK,     button_callback);    //按键双击触发一次
button_attach(&btn1, LONG_PRESS_START, button_callback);    //按键长按触发一次
?
button_start(&btn1);

以上准备就绪后,还剩下最后一个步骤,以5ms的周期定时调用按键状态处理函数:

代码语言:javascript
复制
while(1)
{
    if(cnt_1ms >= 5)
    {
        cnt_1ms = 0;
        button_ticks();
    }
}

1ms我是采用的定时器中断的方式进行计数。

代码语言:javascript
复制
//Timer0 interrupt handler
void TIMER0_Handler(void)
{
    if(TIMER_GetIRQStatus(TIMER0) != RESET)
    {
        cnt_1ms++;
        TIMER_ClearIRQ(TIMER0);
    }
}

这样就完成了MultiButton在高云GW1NSR-4C FPGA上的移植。

4. 测试与运行

编译,下载bin文件,打开串口助手,并开启时间戳显示,分别测试按键按下、抬起、单击、双击、长按等触发方式。

测试日志如下:

代码语言:javascript
复制
//单击测试1
PRESS_DOWN      [2023-09-23 09:25:10.789]
PRESS_UP        [2023-09-23 09:25:10.974]
SINGLE_CLICK    [2023-09-23 09:25:11.274]
//单击测试2
PRESS_DOWN      [2023-09-23 09:25:13.596]
PRESS_UP        [2023-09-23 09:25:13.783]
SINGLE_CLICK    [2023-09-23 09:25:14.093]
//双击测试1,300ms内两次按下    
PRESS_DOWN      [2023-09-23 09:25:15.017]
PRESS_UP        [2023-09-23 09:25:15.148]
PRESS_DOWN      [2023-09-23 09:25:15.214]
PRESS_UP        [2023-09-23 09:25:15.332]
DOUBLE_CLICK    [2023-09-23 09:25:15.647]
//双击测试2,300ms内两次按下   
PRESS_DOWN      [2023-09-23 09:25:17.589]
PRESS_UP        [2023-09-23 09:25:17.689]
PRESS_DOWN      [2023-09-23 09:25:17.758]
PRESS_UP        [2023-09-23 09:25:17.906]
DOUBLE_CLICK    [2023-09-23 09:25:18.214]
//长按测试1,识别时间1000ms    
PRESS_DOWN      [2023-09-23 09:25:18.896]
LONG_PRESS_START[2023-09-23 09:25:19.910]
PRESS_UP        [2023-09-23 09:25:20.711]
//长按测试2,识别时间1000ms   
PRESS_DOWN      [2023-09-23 09:25:21.698]
LONG_PRESS_START[2023-09-23 09:25:22.702]
PRESS_UP        [2023-09-23 09:25:23.003]

按键触发的灵敏度,单击、双击、长按的识别时间阈值,可以在头文件中进行修改:

代码语言:javascript
复制
//According to your need to modify the constants.
#define TICKS_INTERVAL    5 //ms
#define DEBOUNCE_TICKS    3 //MAX 7 (0 ~ 7)
#define SHORT_TICKS       (300  / TICKS_INTERVAL)
#define LONG_TICKS        (1000 / TICKS_INTERVAL)
#define LONG_HOLD_CYC     (500 / TICKS_INTERVAL)

以上是默认条件,按下并保持1000ms认为是长按。

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. MultiButton简介
    • 2. MultiButton代码获取
      • 3. MultiButton移植
        • 4. 测试与运行
        相关产品与服务
        FPGA 云服务器
        FPGA 云服务器提供FPGA开发和使用工具及环境,让用户轻松获取并 部署FPGA计算实例,专注于FPGA硬件加速应用开发,为您提供易用、可重构、经济、安全的FPGA云服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com