鸿蒙开发板外设控制 之 实现物理按键的“长按事件”(按键通用框架 V0.0.2)
我在之前的帖子《实现按键“按下事件”和“释放事件”的通用框架(V0.0.1)》中阐述了DTButton-V0.0.1的设计思路,并且也在帖子中开源了实现代码。
实现这个框架的意图非常明显,就是为了偷懒,想要响应按键事件的时候可以一行代码搞定。也正是因为只想偷懒,V0.0.1版本在实现上非常的简单粗暴:快速实现功能即可,其它问题暂时不考虑。
核心实现代码如下:

有同学可能会说:这样实现有什么问题吗?看起来合情合理,用起来也没问题啊!
是的!从功能实现角度,这样做是最简单的,代码量最少,能立即可用。然而,大家也需要意识到:OnButtonPressed() 和 OnButtonReleased() 是在中断上下文中调用的!因此,这两个函数必须快速返回,不能做过于繁重的工作。但是作为框架,这两个中断函数又必须调用相应的回调函数。。。这样子的话,就要求传入的回调函数必须短小精悍,不能过于繁琐!!于是,V0.0.1版本的实现短板就凸显了:当按键按下后需要做的处理必须足够简单,如果比较复杂和繁琐,就可能造成系统中断响应不及时,进而导致系统PANIC重启!!!(如果不了解中断的概念,可自行查阅相关资料,也可以看看我的操作系统视频课程。)
那么有没有办法解决这个问题呢?
办法当然是有的!!既然V0.0.1版本的问题和中断响应相关,那么可以借鉴Linux内核中的原则和方案:中断服务程序的执行越快越好,将中断处理分为两部分:中断处理上半部和中断处理下半部。
解释:
中断发生后需要立即调用中断服务程序进行中断处理,如果直接在中断服务程序中做这个处理,那么处理速度必须越快越好!
但是,肯定有一些情况的处理步骤是比较耗时和复杂的,在这种情况下,就可以先把要做的处理工作进行标记(中断上半部),具体处理步骤在中断服务程序返回后再完成(中断下半部)。
是不是感觉很抽象,理解不了了?! 没关系,我们通过V0.0.2版本的设计实现给大家讲解这个方案。

上图中的示例就是DTButton - V0.0.2的核心实现,现在应该感觉很简单了吧。嘿嘿!因为是通用框架,所以最终的代码实现要考虑的东西很多,比上图中的示例看起来要复杂些。
现在,这个框架比起上一个版本有了很大的改进,并且还拥有了专用的事件处理线程!也正是因为创建了这个线程,所以不能浪费啊,必须多多利用才行。
那么还能用它来干点啥呢???
大家想想,现在能够捕捉到按键的按下事件和释放事件了!!
那么,如果按下事件和释放事件之间的时间间隔比较长,那么是不是我们就可以“创造“一个全新的长按事件呢???
答案是肯定的!
按下事件发生后,可以通过事件处理线程进行粗略计时,当计时超过预设的时间间隔(大概2.5秒),即可触发长按事件,具体表现为长按事件回调函数的调用。

这里需要注意:
长按事件只会触发一次,即:OnButtonLongPressed() 回调函数只会调用一次
释放事件触发时需要停止计时,即:按下事件和释放事件之间的时间间隔不足2.5秒就不会触发长按事件
有了上面的分析,大家就可以自己尝试动手实现了。
什么?觉得麻烦?
没事!我已经将实现代码上传到了文末的附件中,大家可以下载使用和研究,非常欢迎大家的意见和建议。
使用示例如下:
定义按键事件回调函数

一键注册,开箱即用

运行结果如下:

后记:
开箱使用之后,相信已经有同学发现了问题:GPIO_5居然对应了Hi3861上的 3 个物理按键!!!!
怎么解决?
嗯,这是 DTButton - V0.0.3 中会重点解决的问题!
希望大家关注这个框架,我会尽力开发,维护和完善它!
Enjoy it!
作者:唐佐林
想了解更多内容,请访问:
51CTO和华为官方战略合作共建的鸿蒙技术社区
https://harmonyos.51cto.com#bky
鸿蒙开发板外设控制 之 实现物理按键的“长按事件”(按键通用框架 V0.0.2)的更多相关文章
- 鸿蒙开发板外设控制 之 实现按键“按下事件”和“释放事件”的通用框架(V0.0.1)
在帖子 <鸿蒙开发板外设控制>直播图文版(2020.10.28) 中我们提到过:"开发板上的按键也可以看作一种 GPIO 外设." 因此,要捕捉按键的状态(按下或释放) ...
- iTOP-4412嵌入式开发板ioremap控制GPIO寄存器
转自迅为电子技术论坛:http://bbs.topeetboard.com GPIO 的寄存器通过 ioremap函数转换之后,可以通过直接控制虚拟地址来控制物理地址(寄存器的实际地址),这样就实现 ...
- 【鸿蒙开发板试用报告】用OLED板实现FlappyBird小游戏(中)
小伙伴们久等了,在上一篇<[开发板试用报告]用OLED板实现FlappyBird小游戏(上)>中,我们本着拿来主义的原则,成功的让小鸟在OLED屏幕上自由飞翔起来,下面我们将加入按钮交互功 ...
- zynq开发板外设配置演示
有幸得到米尔电子zynq系列开发板Z-turn Board试用体验,下面说说我这款zynq系列的Z-TURN板子外设配置.从Z-turn Board原理图上看,目前可以配置的FPGA管脚大概有100多 ...
- 【开发实录】在鸿蒙开发板上使用websocket(移植自librws库)
librws: Tiny, cross platform websocket client C library 相关代码可在下面下载,也可进入librws: 将librws移植到鸿蒙Hi_3861开发 ...
- 【单片机入门】(四)应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
引言 各位大佬,晚上好啊,在上一篇博客中,我们讲了什么是UART串口通讯,以及使用USB转TTL使得单片机可以和c#上位机做一个串口通讯,接下来,为大家带来PWM的概念原理,以及实际案例,使用PWM对 ...
- 【安富莱】V6,V5开发板用户手册,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔(2019-11-04)
说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.本次工程延续以往的代码风格,从底层BSP驱动包到应用代码,变量命名,文件 ...
- 【鸿蒙开发板试用报告】用OLED板实现FlappyBird小游戏(上)
总是做各种Demo,是时候做个什么小应用来练练手了.踌躇了很久,果然还是搞个小游戏才有意思.想到几年前风靡全球的FlappyBird,一个屏幕一个按钮就足够了,正好适合.OLED屏幕.按键的驱动已经有 ...
- STC-51开发板-单片机控制数码管&按键&点阵综合操作
操作: 实现按下一个按键,对应的数码管和点阵显示相应的数字 代码: /* *******************数码管按键综合项目********************* */ #include ...
随机推荐
- 这个网易云JS解密,老网抑云看了都直呼内行
最近更新频率慢了,这不是因为CK3发售了嘛,一个字就是"肝".今天来看一下网易云音乐两个加密参数params和encSecKey,顺便抓取一波某歌单的粉丝,有入库哦,使用mysql ...
- 万万没想到!ModelArts与AppCube组CP了
摘要:嘘,华为云内部都不知道的秘密玩法,我悄悄告诉您! 双"魔"合璧庆双节 ↑开局一张图,故事全靠编 华为云的一站式开发平台ModelArts和应用魔方AppCube居然能玩到一起 ...
- 为Facebook messenger平台开发聊天机器人
介绍 在电子商务网上商店发明之前,我们总是有机会与销售代表或分销商在选择商品或服务时交谈.在进入数字世界后,这个领域变得沉默.这样对顾客方便吗?我认为不是.向销售代表或经销商询问他们想要的产品或服务是 ...
- 草率了,又一个Maven打包的问题
经常遇到 Maven 相关的问题,这是之前的文章: 这个 Maven 依赖的问题,你敢说你没遇到过:https://mp.weixin.qq.com/s/SzBbDtyRUrk_7LH8SUbGXQ ...
- NB 的开源项目遍地开花——GitHub 热点速览 Vol.41
作者:HelloGitHub-小鱼干 本周的 GitHub 热点速览的关键词便是 nb,也是本周特推之一的项目名字,这个功能如名字一般 nb 的项目是一个脚本,帮你处理笔记.书签.归档和知识库应用程序 ...
- docker启动镜像报错
docker启动镜像报错: docker: Error response from daemon: driver failed programming external connectivity on ...
- chrome(谷歌)登录失败解决方案
相信有很多小伙伴和我一样,同步chrome的收藏夹,这样也便于随时可以查看自己收藏的网址.但是同步文件,必须先要登录chrome账号,登录chrome账号时,总是会报黄页,或者一直加载不出来.接下来, ...
- 【线段树】BZOJ 5334 数学计算
题目内容 小豆现在有一个数\(x\),初始值为\(1\).小豆有\(Q\)次操作,操作有两种类型: 1 m:\(x=x×m\),输出\(x\ mod\ M\): 2 pos:\(x=x/\)第\(po ...
- Go语言基础知识01-用Go打个招呼
每一种编程语言,从读一本好书开始 每一种编程语言,也从Helloworld开始 1. 环境准备 1.1 安装golang 在Ubuntu下,直接输入命令可以安装最新版本: $ sudo apt-get ...
- vagrantfile-参考示例
Vagrantfile 文件 bt为你需要新建的box名字 Vagrant.configure("2") do |config| config.vm.box = &qu ...