实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3) 原创 精华

唐佐林
发布于 2020-11-17 22:45
浏览
9收藏

在上一篇帖子《实现S1,S2,User三个物理按键的独立事件-上(解决思路分析)》中,通过读取 HI_ADC_CHANNEL_2 上的 ADC 值成功区分了 S1, S2, User 这 3 个物理按键。

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

上图中的打印输出是分别按下 User, S1, S2 的效果,这看起来完全符合了我们区分按键的需求,但是。。。

 

但是什么呢?有什么问题吗?

 

我想说的是,但是问题非常明显:这三个键中的任意一个被按下都会多次触发按键事件(上图的实验通过打印输出响应按键事件)。因此,仅仅区分 S1, S2, User 还不够,还不能满足实际开发的需要。所以,必须进一步的完善,使得每次按下按键只触发一次事件。

 

看到这里,相信大家想到了之前开源的按键通用框架 DTButton !在 V0.0.2 版中已经可以区分并触发各种 GPIO 按键事件,却唯独区分不了 S1, S2, User。然而,现在已经有了 S1, S2, User 的区分方案,那么将这个方案集成到 DTButton 框架不就完美了吗??!!

 

Ok!说干就干!

 

接下来要做的工作就是:

  1. 将 GetSSU() 集成到框架,使得框架支持 S1, S2, User 的三种事件(Pressed, LongPressed, Released)
  2. 不改变框架的对外接口(不改变框架调用方式,不增加新接口函数)
  3. 不影响框架 V0.0.2 版本的原有功能

 

要做好上述 3 个工作,就需要再回顾一下 DTButton 框架的核心设计:

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

 

GPIO 按键在中断服务程序中标记事件的发生,之后在事件处理线程中通过标记调用事件回调函数(仅一次)!

注意:触发事件后需要立即清除事件标记,防止多次调用回调函数。

 

所以,最简单的集成方式就是:当 S1, S2, User 中有键按下时进行事件标记,之后再通过事件标记调用相应回调函数(返回后清除事件标记)。

 

流程如下:

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

接下来要考虑的问题是:如何构造 S1, S2, User 的按下事件和释放事件?

 

要解决这个问题,可以参考一般 GPIO 按键的事件触发方式:上升沿触发下降沿触发。然而,相信你也意识到了,S1, S2, User 是通过检测 ADC 值来判断区分的,无法像 GPIO 按键那样直接准确的捕获上升沿和下降沿。怎么办呢???直接不行,可以间接:通过模拟上升沿和下降沿构造释放事件和按下事件。

 

具体方法如下:

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

在代码层面可以用变量 preKey 记录上一次通过 GetSSU() 获得的按键状态,并与当前调用 GetSSU() 获得的按键状态进行比较,比较结果即可判断是否构造按键事件。

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

有了以上分析就可以动手写出下面的代码了!

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

之后,整个框架以统一的方式处理按键事件,不管是 S1, S2, User 还是 GPIO 按键,但凡触发了事件都会在 EventHandler() 得到处理。

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

 

到此,按键通用框架 V0.0.3 版的设计就完成了!具体代码实现已开源(文末附件下载),开箱即用。

 

使用示例如下:

实现S1,S2,User三个物理按键的独立事件-下(DTButton-V0.0.3)-鸿蒙开发者社区

一样的接口,一样的方式,一样的体验,多出来的仅是对 S1, S2, User 三个物理按键的区分支持。

 

Enjoy It!

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
DTButton-V0.0.3.zip 5.12K 187次下载
已于2020-12-16 16:29:38修改
12
收藏 9
回复
举报
13条回复
按时间正序
/
按时间倒序
gordonlonglong
gordonlonglong

大佬好文!感谢分享!!!

1
回复
2020-11-18 14:16:24
红叶亦知秋
红叶亦知秋

对老师的不断探索的精神由衷的佩服,感谢老师的分享

1
回复
2020-11-18 14:16:42
SummerRic
SummerRic

老师果然一出,必精华啊。

回复
2020-11-19 14:32:07
鸿蒙开发者社区官方账号
鸿蒙开发者社区官方账号

翻个牌子,好的内容让大家再多看一会。耶~

1
回复
2020-11-20 16:33:27
笔架鱼052
笔架鱼052

好文章,请教一下,将三个物理按键 分别用ID 15 16 17指代,后面调用  与GPIO相关操作 IoSetFunc /dir/vaule /register isr 时,不会报错吗?  因为实际上IC上 是没有这几个ID的。 

1
回复
2021-4-14 20:23:37
笔架鱼052
笔架鱼052 回复了 笔架鱼052
好文章,请教一下,将三个物理按键 分别用ID 15 16 17指代,后面调用 与GPIO相关操作 IoSetFunc /dir/vaule /register isr 时,不会报错吗? 因为实际上IC上 是没有这几个ID的。

我这边的问题, 已经看到相关代码了。 抱歉

回复
2021-4-15 09:56:08
休止符、
休止符、

老师,为什么和样例一样的代码复制到我的文件会报错呢?

回复
2021-9-1 09:24:32
爱吃土豆丝的打工人
爱吃土豆丝的打工人

好文  三连跟上、

回复
2021-9-1 09:46:24
唐佐林
唐佐林 回复了 休止符、
老师,为什么和样例一样的代码复制到我的文件会报错呢?

从错误信息来看是链接出问题,你看看代码是否被编译,检查一下你的程序设置,比如:build.gn

 

static_library("dt_btn_demo") {

    sources = [

        "dt_btn_demo.c",

        "dt_btn_util.c"

    ]

 

    include_dirs = [

        "//utils/native/lite/include",

        "//kernel/liteos_m/components/cmsis/2.0",

        "//base/iot_hardware/interfaces/kits/wifiiot_lite",

        "//vendor/hisi/hi3861/hi3861/include"

    ]

}

回复
2021-9-8 17:38:56
mb5ff32ad51fb81
mb5ff32ad51fb81

唐老师,现在2.0代码里面没有wifiiot_gpio_ex.h这个文件了,怎么处理

回复
2021-9-16 15:24:45
唐佐林
唐佐林 回复了 mb5ff32ad51fb81
唐老师,现在2.0代码里面没有wifiiot_gpio_ex.h这个文件了,怎么处理

我稍后更新一下代码。

用原生API开发是会有版本升级带来的问题。

你可以关注一下我的Python开源项目,我会把底层版本变动封装好,让API不因为版本升级而发生变动。

回复
2021-9-16 17:36:27
mb5ff32ad51fb81
mb5ff32ad51fb81 回复了 唐佐林
我稍后更新一下代码。 用原生API开发是会有版本升级带来的问题。 你可以关注一下我的Python开源项目,我会把底层版本变动封装好,让API不因为版本升级而发生变动。

你讲python课的时候,我在线上听了,虽然我不太懂python,但是你的鸿蒙python实现就像一场革命一样

1
回复
2021-9-18 14:32:38
唐佐林
唐佐林 回复了 mb5ff32ad51fb81
你讲python课的时候,我在线上听了,虽然我不太懂python,但是你的鸿蒙python实现就像一场革命一样

谢谢! 我会努力更新这个 Python 项目。

回复
2021-9-18 21:56:41
回复
    相关推荐