修复bug:FlexibleButton id相反问题

news2024/11/17 5:57:01

目录

版本:https://github.com/murphyzhao/FlexibleButton/releases/tag/2.0.1

问题现象

问题描述

查源码!

注册

读按键

按键处理

小结


版本:https://github.com/murphyzhao/FlexibleButton/releases/tag/2.0.1https://github.com/murphyzhao/FlexibleButton/releases/tag/2.0.1

问题现象

static uint8_t common_btn_read(void *arg)
static void common_btn_evt_cb(void *arg)

这两个用户代码中的ID是相反的

问题描述

typedef enum
{
    USER_BUTTON_1 = 0,
    USER_BUTTON_2,
    USER_BUTTON_3,
//    USER_BUTTON_4,
    USER_BUTTON_MAX
} user_button_t;
    case USER_BUTTON_1:
        value = PEin(6);
        break;
    case USER_BUTTON_2:
        value = PCin(7);
        break;
    case USER_BUTTON_3:
        value = PEin(5);
        break;
static void common_btn_evt_cb(void *arg)
{
    flex_button_t *btn = (flex_button_t *)arg;

    DEBUG("id: [%d - %s]  event: [%d - %30s]  repeat: %d\r\n", 
        btn->id, enum_btn_id_string[btn->id],
        btn->event, enum_event_string[btn->event],
        btn->click_cnt);
}

正常逻辑 再回调 id = 0的时候应该对应的是 USER_BUTTON_1 (PE6)

实际测试的情况是 id = 0的时候应该对应的是 USER_BUTTON_3 (PE5)

顺序正好是逆序。其他功能都是正常的,虽然能用但是非常不爽。

查源码!

注册

static void user_button_init(void)
{
    int i;


    memset(&user_button[0], 0x0, sizeof(user_button));
   
    for (i = 0; i < USER_BUTTON_MAX; i ++)
    {
        user_button[i].id = i;
        user_button[i].usr_button_read = common_btn_read;
        user_button[i].cb = common_btn_evt_cb;
        user_button[i].pressed_logic_level = 0;
        user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);
        user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(3000);
        user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(4500);

        flex_button_register(&user_button[i]);
    }
}
    /**
     * First registered button is at the end of the 'linked list'.
     * btn_head points to the head of the 'linked list'.
    */
    button->next = btn_head;
    button->status = FLEX_BTN_STAGE_DEFAULT;
    button->event = FLEX_BTN_PRESS_NONE;
    button->scan_cnt = 0;
    button->click_cnt = 0;
    button->max_multiple_clicks_interval = MAX_MULTIPLE_CLICKS_INTERVAL;
    btn_head = button;

可以看到原作者这里使用了链表,如下图

读按键

/**
 * @brief Read all key values in one scan cycle
 * 
 * @param void
 * @return none
*/
static void flex_button_read(void)
{
    uint8_t i;
    flex_button_t* target;

    /* The button that was registered first, the button value is in the low position of raw_data */
    btn_type_t raw_data = 0;

    for(target = btn_head, i = button_cnt - 1;
        (target != NULL) && (target->usr_button_read != NULL);
        target = target->next, i--)
    {
        raw_data = raw_data | ((target->usr_button_read)(target) << i);
    }

    g_btn_status_reg = (~raw_data) ^ g_logic_level;
}

重点看这里面的i;

原作者使用了一个32位的变量存放按键值,每个bit对应一个按键值;

typedef uint32_t btn_type_t;

读代码里面是这样对应的。

按键处理

/**
 * @brief Handle all key events in one scan cycle.
 *        Must be used after 'flex_button_read' API
 * 
 * @param void
 * @return none
*/
static void flex_button_process(void)
{
    uint8_t i;
    flex_button_t* target;

//    for (target = btn_head, i = 0; target != NULL; target = target->next, i ++)
		for (target = btn_head, i = button_cnt - 1; target != NULL; target = target->next, i--)
    {
        if (target->status > FLEX_BTN_STAGE_DEFAULT)
        {
            target->scan_cnt ++;
            if (target->scan_cnt >= ((1 << (sizeof(target->scan_cnt) * 8)) - 1))
            {
                target->scan_cnt = target->long_hold_start_tick;
            }
        }

        switch (target->status)
        {
        case FLEX_BTN_STAGE_DEFAULT: /* stage: default(button up) */
            if (BTN_IS_PRESSED(i)) /* is pressed */
            {
                target->scan_cnt = 0;
                target->click_cnt = 0;

                EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_DOWN);

                /* swtich to button down stage */
                target->status = FLEX_BTN_STAGE_DOWN;
            }
            else
            {
                target->event = FLEX_BTN_PRESS_NONE;
            }
            break;

        case FLEX_BTN_STAGE_DOWN: /* stage: button down */
            if (BTN_IS_PRESSED(i)) /* is pressed */
            {
                if (target->click_cnt > 0) /* multiple click */
                {
                    if (target->scan_cnt > target->max_multiple_clicks_interval)
                    {
                        EVENT_SET_AND_EXEC_CB(target, 
                            target->click_cnt < FLEX_BTN_PRESS_REPEAT_CLICK ? 
                                target->click_cnt :
                                FLEX_BTN_PRESS_REPEAT_CLICK);

                        /* swtich to button down stage */
                        target->status = FLEX_BTN_STAGE_DOWN;
                        target->scan_cnt = 0;
                        target->click_cnt = 0;
                    }
                }
                else if (target->scan_cnt >= target->long_hold_start_tick)
                {
                    if (target->event != FLEX_BTN_PRESS_LONG_HOLD)
                    {
                        EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_HOLD);
                    }
                }
                else if (target->scan_cnt >= target->long_press_start_tick)
                {
                    if (target->event != FLEX_BTN_PRESS_LONG_START)
                    {
                        EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_START);
                    }
                }
                else if (target->scan_cnt >= target->short_press_start_tick)
                {
                    if (target->event != FLEX_BTN_PRESS_SHORT_START)
                    {
                        EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_SHORT_START);
                    }
                }
            }
            else /* button up */
            {
                if (target->scan_cnt >= target->long_hold_start_tick)
                {
                    EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_HOLD_UP);
                    target->status = FLEX_BTN_STAGE_DEFAULT;
                }
                else if (target->scan_cnt >= target->long_press_start_tick)
                {
                    EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_LONG_UP);
                    target->status = FLEX_BTN_STAGE_DEFAULT;
                }
                else if (target->scan_cnt >= target->short_press_start_tick)
                {
                    EVENT_SET_AND_EXEC_CB(target, FLEX_BTN_PRESS_SHORT_UP);
                    target->status = FLEX_BTN_STAGE_DEFAULT;
                }
                else
                {
                    /* swtich to multiple click stage */
                    target->status = FLEX_BTN_STAGE_MULTIPLE_CLICK;
                    target->click_cnt ++;
                }
            }
            break;

        case FLEX_BTN_STAGE_MULTIPLE_CLICK: /* stage: multiple click */
            if (BTN_IS_PRESSED(i)) /* is pressed */
            {
                /* swtich to button down stage */
                target->status = FLEX_BTN_STAGE_DOWN;
                target->scan_cnt = 0;
            }
            else
            {
                if (target->scan_cnt > target->max_multiple_clicks_interval)
                {
                    EVENT_SET_AND_EXEC_CB(target, 
                        target->click_cnt < FLEX_BTN_PRESS_REPEAT_CLICK ? 
                            target->click_cnt :
                            FLEX_BTN_PRESS_REPEAT_CLICK);

                    /* swtich to default stage */
                    target->status = FLEX_BTN_STAGE_DEFAULT;
                }
            }
            break;
        }
    }
}

注释掉的部分是源代码,下面是我修改之后的代码。 

这里也是重点看“i”。

在遍历链表的时候,

BTN_IS_PRESSED(i)

原作者代码的i对应关系是,USER_BUTTON_3的链表使用了USER_BUTTON_1 引脚读取到的值。

那我们只要按照我上面给出的代码修改之后对应关系就正常了。

小结

原作者写的这份代码非常优秀,无论是实现的功能/可以执行都比我高出很多。具体就是在数据结构设计的时候我目前为止没有设计过带链表的数据结构,作者再这里面通过链表实现这些功能真的巧妙。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

00后自述,生活所迫,不卷一点我能怎么办?

前段时间我去面试了一个软件测试公司&#xff0c;成功拿到了offer&#xff0c;薪资也从10k涨到了15k&#xff0c;对于工作都还没两年的我来说&#xff0c;还是比较满意的&#xff0c;毕竟有些工作了3到4年的可能还没有我的高。 在公司一段时间后大家都说我是卷王&#xff0c;其…

MySQL5.7数据导入/导出、TiDB数据回迁移

一、环境&安装包 CentOS Linux release 7.4.1708 (Core)TDSQL&#xff08;腾讯基于MySQL5.7.x自主研发的数据库&#xff09;Mysqldump&#xff08;MySQL5.7.41备份客户端&#xff09;Dumpling&#xff08;mydumper 的全新升级版&#xff09;Myloader&#xff08;mydumper附…

Flutter 3.10 之 Flutter Web 路线已定,可用性进一步提升,快来尝鲜 WasmGC

随着 Flutter 3.10 发布&#xff0c;Flutter Web 也引来了它最具有「里程碑」意义的更新&#xff0c;这里的「里程碑」不是说这次 Flutter Web 有多么重大的更新&#xff0c;而是 Flutter 官方对于 Web 终于有了明确的定位和方向。 提升 首先我们简单聊提升&#xff0c;这不是…

用处巨广的操作符,快来学学叭(C语言版)

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C知识系统分享》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c…

buildroot 目录结构

buildroot 目录结构 board 存放着不同厂商相关的文件 buildroot-2023.02/board/sipeed/lichee_rv_dock里面描述了如何连接wifi,蓝牙&#xff0c;烧写sdcard.img 如何配置buildroot和编译等 make sipeed_lichee_rv_dock_defconfig makearch 存放着CPU相关的文件&#xff0c…

SQLite:轻量级嵌入式数据库

原创 | 文 BFT机器人 引言 SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。就像其他数据库&#xff0c;SQLite 引擎不…

AI —— 亲测讯飞星火认知大模型,真的很酷!

讯飞星火认知大模型真的很酷&#xff01; 前言&#x1f64c;讯飞星火认知大模型基本的使用介绍与讯飞星火认知大模型基本的对话 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xf…

FE_Vue学习笔记 条件渲染[v-show v-if] 列表渲染[v-for] 列表过滤 列表排序

1 条件渲染 v-show v-if 使用template可以使其里面的内容在html的结构中不变。条件渲染&#xff1a; v-if 1&#xff09;v-if“表达式” 2&#xff09;v-else-if“表达式” 3&#xff09;v-else {} 适用于&#xff1a;切换频率较低的场景。特点&#xff1a;不展示的DOM元素直…

rem、px、em的区别 -前端

文章目录 三者的区别特点与换算举例emrem 总结一总结二 三者的区别 在css中单位长度用的最多的是px、em、rem&#xff0c;这三个的区别是&#xff1a; 一、px是固定的像素&#xff0c;一旦设置了就无法因为适应页面大小而改变。 二、em和rem相对于px更具有灵活性&#xff0c;…

消息认证码以及数字签名的认识

文章目录 消息认证码及数字签名1. 消息认证码1.1 消息认证1.2 消息认证码的使用步骤1.3 go中对消息认证码的使用1.4 消息认证码的问题 2.数字签名2.1 数字签名的生成和验证2.2 数字签名的流程2.3 Go使用RSA进行数字签名2.4 Go使用椭圆曲线进行数字签名2.5 数字签名无法解决的问…

dts pinctrl初始gpio0方法

1、在pinctrl-rockchip.c文件中添加头文件 #include <linux/of_gpio.h> 如下 2、 在如下函数添加红色代码 static int rockchip_pinctrl_probe(struct platform_device *pdev) { struct rockchip_pinctrl *info; struct device *dev &pdev->dev; …

Vue3 自定义指令让元素自适应高度,el-table在可视区域内滚起来

我始终坚持&#xff0c;前端开发不能满足于实现功能&#xff0c;而是需要提供优秀的交互与用户体验。即使没有产品没有UI的小项目&#xff0c;也可以自己控制出品质量&#xff0c;做到小而美。所以前端们不仅仅需要了解框架如何用&#xff0c;还要学习一些设计、交互、体验的知…

新入职了一个00后卷王,天天加班12点,太让人崩溃......

在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事&#xff0c;可遇不可求&#xff0c;向他学习还来不及呢。 真正让人反感的&#xff0c;是技术平平&…

Android 百度地图SDK闪退

Android 百度地图SDK闪退 通过Android IDE查看APP运行日志Error 1:errorcode: 230 uid: -1 appid -1 msg: APP Mcode码校验失败 在调用百度SDK时出现闪退现象&#xff0c;要知道闪退的具体原因&#xff0c;不然搜了一堆教程&#xff0c;发现纯纯浪费时间&#xff0c;作者也是痛…

知识就是力量,图谱路在何方 | ChatGPT冲击下,招商银行如何“抢救”知识图谱?

“知识就是力量”我们耳熟能详&#xff0c;但培根的这句话其实还有后半句“更重要的是运用知识的技能”。对于人工智能来说&#xff0c;知识图谱就是其如何对知识进行运用的技能体现。在金融领域&#xff0c;如何运用这一技能更好地理解客户需求&#xff0c;提高业务效率和客户…

三层架构与MVC架构区别

三层架构 表示层&#xff1a;主要对用户的请求接受&#xff0c;以及数据的返回&#xff0c;为客户端提供应用程序的访问。 servlet层 业务逻辑层&#xff1a;对我们数据实现业务逻辑的封装 service层 数据访问层&#xff1a;对数据库访问操作 dao层 MVC架构 1.MVC全名是Model …

MATLAB 常用数学函数和数组和字符串、元胞数组和结构体,MATLAB 编程,关系运算符和逻辑变量

目录 MATLAB 零基础学习 简介 使用平台 一、MATLAB 界面 二、基础操作 使用方法 常用数学函数 初等函数 三角函数 指数和对数 复数 标点符号 常用操作 三、文件类型 数组 一、数组基础知识 二、数组创建与操作 创建 数组操作 字符串数组 字符串、元胞数组…

语义分割学习笔记(三)FCN网络结构详解

1.FCN网络概述 FCN网络&#xff08;Fully Convolutional Networks&#xff09;&#xff1a;首个端对端的针对像素级预测的全卷积网络。 FCN网络思想&#xff1a;输入图像经过多次卷积&#xff0c;得到一个通道数为21的特征图&#xff0c;再经过上采样&#xff0c;得到一个与原图…

如何在 Mac 或 Windows 上将 PDF 转换为 Word 而不丢失格式

PDF 有无数的优点&#xff0c;但它不能像 Microsoft Word 文档那样容易编辑。如果您没有价格总是很高的 PDF 编辑器&#xff0c;您将无法根据需要编辑或使用 PDF 源。但是我们可以将PDF转成Word&#xff0c;方便编辑。 有很多解决方案可用于在 Mac 上将 PDF 转换为可编辑的 W…

纯手动搭建大数据集群架构_记录019_集群机器硬盘爆满了_从搭建虚拟机开始_做个200G的虚拟机---大数据之Hadoop3.x工作笔记0179

今天突然就发现,使用nifi的时候集群满了...气死了.. 而在vmware中给centos去扩容,给根目录扩容,做的时候,弄了一天...最后还是报错, 算了从头搭建一个200G的,希望这次够用吧.后面再研究一下扩容的问题. 2023-05-12 11:06:48 原来的集群的机器,硬盘太小了,扩容不知道怎么回事…