利用队列收集单双击和长按按键
利用队列收集单双击和长按按键
引言
当我们仅仅通过在while循环里面进行判断按键类型的标志位, 然后进行操作的时候, 我们的最小例程很小, 所以能够实时的检测到按键,从而触发实验现象.
![]()
假如我们此时进入了一个事件处理函数呢 ? 并且这个这个函数的操作是不可被打断的, 如果此时我们重复按下多次按键, 标志位只能存放一个数值, 等事件处理完, 我们再处理的时候, 只能处理最后一次按下的按键类型.
![]()
最常见的就是, 我们使用遥控器, 我们连着按下了多个下箭头, 因为电视太卡, 导致只向下一次, 会极大影响操作体验.
所以我们的需求就是, 虽然你现在可能有重要事情要做, 但是, 你可以把我的按键需求存下来, 等不忙的时候, 再来处理. 因为处理器的处理是很快的, 所以我们也不会耽搁太多的时间。
按键收集模型分析
对于按键的收集, 我们分成三种类型,单击,双击和长按, 并且我们是按顺序按下的, 按顺序处理的, 所以这很符合队列的模型, 我们把他们排成一排, 放进数组, 然后到处理的时候, 再按顺序, 逐个处理, 按键需求和用户需求保持一致即可.
按键收集时机
对于按键收集, 假如现在我们有重要的事情去做, 不能立即去处理按键的功能, 但是我们可以中断的去收集按键类型, 因为中断是不会耽搁时间的. 只是花费CPU去记录一下数据. 所以我们在定时器函数内, 判断按键类型的时候, 把按键类型 button_mode 收集到队列里面。

按键收集队列
我们采用数组存储, 定义一个队头,定义一个队尾,加入按键的时候,我们放在队尾, 处理按键的时候, 我们拿取队头按键处理。
初始化时候
队首,队尾都指向数组初始的时候
加入一个按键的时候
此按键, 加入到队尾(位序0), 然后队尾后移, 因为队尾始终要承载按键, 所以后移, 为后续腾出位置
加入两个按键的时候
把按键2,加入队尾, 位序为1处, 然后队尾后移到位序2
所以, 在收集按键的时候, 我们定义一个数组, 队尾一直后移, 因为我们相当于一个循环队列, 所以队尾后移到最大位序的时候, 可以再次回到开头, 继续添加(这里有一个前提就是, 我们一次性处理的数据, 不能超过数组的最大位序, 保证出队和入队的正常运转即可)。
void collect_button(void)
{//采集按键信息button_order[button_send] = button_mode;if(button_send >= 5) // 说明5的位置已经被填了,下个该0了(++后,所指位置为空){button_send = 0;}else{button_send++;}
}
按键队列处理
有加入,就有取出。所以当我们取出按键的时候, 把队头按键取出, 处理此按键, 然后队头后移.
直到队头和队尾的数组位序重合, 那么我们就可以宣布,按键处理完毕了
取出按键
按键处理完毕的时候
当队头对应的按键处理完的时候, 我们队头后移, 为下次抽取按键做准备, 但是当队头和队尾 , 重合的时候, 就代表我们没有按键需要处理了.(队尾实时指向的位置, 是为下一次加入队列的按键做准备的, 所以是空的)
代码实现
我们一边处理着按键, 一边判断着队首和队尾是否重合, 一旦重合就代表着我们按键处理完了.
当 button_deal 队首 和 button_send 队尾 不重合时, 就一直取出按键
每次处理完一个按键后, 队尾位序后移, 同时要记得我们是数组,所以容量总会有不够用的时候, 所以我们要回到开头, 继续添加, 逻辑上是连在一起的(只需要保证同时处理的按键总和小于数组总容量即可)
void oled_chose(void)
{//下面是原子时间,不可被定时器新加命令button_atom = 1;//if(button_deal != button_send)//如果有按键指令while(button_deal != button_send ) //直到处理完指令{button_down = 1; //代表已经有指令了//(短按 1, 双按 2, 长按 3)if(button_order[button_deal] == 1){if(now_mode[0] == 1){now_mode[1] ^= 1;}elseif(now_mode[0] == 2)//歌曲选择{if(now_mode[1] == 3){now_mode[1] = 0;}else{now_mode[1]++;}}elseif(now_mode[0] == 3)//歌曲播放页面{//开关歌曲now_mode[2] ^= 1;}}elseif(button_order[button_deal] == 2) //(双击){switch(now_mode[0]){case 1:break; //没想好干啥case 2:now_mode[0] = 3;//进入音乐播放界面now_mode[2] = 1;//播放按钮打开break;case 3:now_mode[0] = 2;//返回音乐菜单now_mode[2] = 0;//播放按钮关闭break;default:break;}} else if(button_order[button_deal] == 3)//长按{if(now_mode[0] == 1){now_mode[0] = 2;//切换为音乐模式now_mode[1] = 0;//音乐界面默认第一个now_mode[2] = 0;//播放按钮也关闭}else{now_mode[0] = 1;//切换为智能模式now_mode[1] = 0;//界面默认第一个now_mode[2] = 0;//播放按钮也关闭}}//然后跳到下一位,接着判断是否重合if(button_deal >= 5) //队尾始终为空,向目标前进{button_deal = 0;}else{button_deal++;}}//可以接受新命令button_atom = 0;
}
注意, 我们这里队首处理完按键,并没有清除其数据, 而是位序往后走, 去覆盖了,队尾移动到此处, 相当于默认此处数据可覆盖, 所以就默认清除了. 要注意,同时我们也可以进行清除, 处理完队头后, 对数组此处赋值一个特定的数值, 方便后续我们调试.
相关文章:

利用队列收集单双击和长按按键
利用队列收集单双击和长按按键 引言 当我们仅仅通过在while循环里面进行判断按键类型的标志位, 然后进行操作的时候, 我们的最小例程很小, 所以能够实时的检测到按键,从而触发实验现象. 假如我们此时进入了一个事件处理函数呢 ? 并且这个这个函数的操作是不可被打断的, 如果此…...

AI工作流:低代码时代的革新者,重塑手机问答类应用生态
在这个数字化迅猛发展的时代,低代码技术正以惊人的速度改变着我们的生活方式。作为低代码人群的先锋,AI工作流技术正在以前所未有的方式,赋予非技术人群实现梦想的能力 🔥能用AI-低代码传送门:https://www.nyai.chat …...

配置MySQL主从,配置MySQL主主 +keeplive高可用
在大数据-Hadoop体系中 配置MySQL主主keeplive高可用 注意:这个是我两年前的word文档,可以当作参考文档有个思路参考一下,但是里面可能有些地方有误 另外 :关于一些企业级实战技术可以参考这篇mysql 物理备份 MySQL 全量备份 增量备份 差异…...

第5节:Elasticsearch核心概念
我的后端学习笔记大纲 我的ElasticSearch学习大纲 1.Lucene和Elasticsearch的关系: 1.Lucene:最先进、功能最强大的搜索库,直接基于lucene开发,非常复杂,api复杂2.Elasticsearch:基于lucene,封装了许多luc…...

存储实验:华为异构存储在线接管与在线数据迁移(Smart Virtualization Smart Migration 特性)
目录 目的实验环境实验步骤参考文档1. 主机安装存储多路径2. v2存储创建Lun,映射给主机;主机分区格式化,写数据3. 将v2存储映射该成映射到v3存储上(v3存储和v2之间链路搭建,测通,远端设备)(Smar…...

职业院校云计算实训室建设方案全景剖析
在信息化社会的今天,云计算作为一项关键技术,正在迅速改变着教育和培训的方式。本文旨在探讨如何通过"职业院校云计算实训室建设方案",为学生提供一个现代化、高效的学习和研究环境,以适应云计算技术的发展和市场需求。…...

VS Code安装与vue项目新建
1、下载安装node.js、VS Code node.js官网下载 Visual Studio Code官网下载 # 查看node.js是否安装成功 node -v npm -v # 定义镜像路径 npm config set registry https://registry.npmmirror.com # 查看是否配置成功 npm config get# 安装webpack npm install webpack -g #…...

如何在Java中将数据库查询结果转换为枚举类型
前言 在开发过程中,我们经常需要将从数据库获取的字符串或数字转换为更具语义的枚举类型。这不仅可以提高代码的可读性,还可以确保类型安全。这时候我们从数据库查出来的值如何通过枚举转换返回? 1. 构建枚举类型 首先,我们需要…...

秋招突击——8、20——知识补充——Java容器
文章目录 引言正文总览ArrayListLinkedListQueue & Stack & ArrayDequePriorityQueueHashSet & HashMapLinkedHashSet & LinkedHashMapTreeSet & TreeMap 面…...

IOS 06 OC调用Swift第三方框架
前面文章05讲的是在OC项目中,调用Swift代码,而在真实开发过程中,在OC项目中调用Swift第三方框架场景用的是非常多的,所以我们也了解在OC项目如何使用Swift写的三方框架。 实现流程: 1、OCUseSwiftTest;在…...

SAP和致远OA系统集成案例
一、项目介绍 重庆某控股(集团)有限公司是一家集合汽柴油动力及终端、摩托车、储能电源、汽车零部件、金融服务等产业的多元化集团公司,业务遍布全球80多个国家及地区,2021年营业收入达80亿元。 为推动集团信息化、数字化转型…...

19 OptionMenu 组件
OptionMenu 组件使用指南 Tkinter 的 OptionMenu 组件是一个下拉选择框,允许用户从一组预定义的选项中选择一个。它通常用于提供用户一个有限的选项集合来选择。以下是对 OptionMenu 组件的详细说明和一个使用案例。 OptionMenu 组件属性 variable: 与 OptionMen…...

【C语言】字符函数与字符串函数(上)
字符函数与字符串函数(上) 文章目录 字符函数与字符串函数(上)1.字符分类函数2.字符转换函数3.strlen的使用和模拟实现3.1使用示例:3.2模拟实现 4.strcpy的使用和模拟实现4.1使用示例:4.2模拟实现 5.strcat的使用和模拟…...

机器学习系列—深入探索弗里德曼检验:非参数统计分析的利器
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...

【ubutnu18.04】k8s 部署4: worker节点配置1.31.0和containerd 1.7.20
上一篇:【ubutnu24.04】k8s部署3:重新安装1.31.0并init成功 worker 节点之一是ubuntu18.04主要参考 How Install Kubernetes on Ubuntu 24.04 (Step-by-Step Guide) 重点参考 ubuntu24.04 作为master反复配置kubelet root@PerfSvr:/home/zhangbin/perfwork/k8sadmin# sudo kub…...

android kotlin集成WorkManager实现定时获取数据
在Android中使用Kotlin集成WorkManager来实现定时获取数据是一个很常见的需求。WorkManager可以帮助你在设备处于闲置或应用被关闭时执行后台任务,特别适用于需要在特定时间间隔内重复执行的任务。以下是实现步骤: 1. 添加依赖项 首先,在你…...

BvSP_ Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction
BvSP: Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction 英文题目BvSP: Broad-view Soft Prompting for Few-Shot Aspect Sentiment Quad Prediction中文题目BvSP:面向少样本方面情感四元预测的广视角软提示论文地址aclanthology.org/202…...

React+Vis.js(05):vis.js的节点的点击事件
文章目录 需求实现思路抽屉实现完整代码需求 双击节点,弹出右侧的“抽屉”,显示节点的详细信息 实现思路 vis.network提供了一个doubleClick事件,代码如下: network.on(doubleClick, function (properties) {// console.log(nodes);let id = properties...

今日(2024 年 8 月 19 日)科技新闻
科大讯飞推出星火极速超拟人交互:8 月 19 日,科大讯飞宣布星火语音大模型更新,正式推出星火极速超拟人交互,并将其能力落地在讯飞星火 APP “小星畅聊” 功能中。该交互响应速度更快,能感知用户情绪变化并共情回应&…...

Python 虚拟环境
为什么要创建虚拟环境 创建 Python 虚拟环境的主要目的是为了解决依赖管理的问题,特别是在开发多个项目或部署应用程序时,虚拟环境具有以下几个优势: 依赖隔离: 不同的项目可能需要不同版本的 Python 解释器和库。通过创建虚拟环…...

Redis RDB三两事
rdb:将数据库的快照以二进制格式保存在文件中,redis重启后直接加载数据。可以通过save和bgsave命令生成rdb。当然我们可以在生成rdb文件时指定规则,例如 save 60 1000 如果60秒内不少于1000个key发生了改动,则生成一个新的rdb文件…...

分布式高可用架构设计
一、限流 1、单机限流 如图,应用C的资源c/x被上游的应用A和应用C并发访问,应用C的系统能力支持c/x资源最高5000/qps的访问量;为了不让高并发流量或尖峰流量压垮应用C,可以针对应用C的资源c/x做限流;比如设置限流4500…...

GATK SampleList接口介绍
在 GATK 中,SampleList 是一个接口,用于表示一个样本列表。这些样本通常是在基因组分析过程中被处理的不同生物样本。SampleList 接口提供了访问这些样本的一些基本方法,通常用于多样本分析任务,比如变异检测或基因组重测序。 SampleList 接口的方法 SampleList 接口定义…...

00后是真卷不过,工作没两年,跳槽到我们公司起薪20K都快接近我了
在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事,我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事,可遇不可求,向他学习还来不及呢。 真正让人反感的,是技术平平&…...

树莓派Pico C/C++ 开发环境搭建(一键完成版)
树莓派Pico C/C 开发环境搭建(一键完成版) 因为之前使用过MicroPython开发过树莓派Pico,总觉得用起来怪怪的。正好最近树莓怕发布了新一代的MCU——RP2350,之前的RP2040在各个平台都有所降价,因此,买了几块。同时因为之前是玩stm…...

【计算机组成原理】二、数据的表示和运算:1.数值与编码(十进制二进制转换、BCD码、ASCII码、汉字编码、奇偶校验码、循环冗余检测CRC、海明码)
二、数据的表示和运算 文章目录 二、数据的表示和运算1.数值与编码1.1数据存储和排列❗1.2十进制转换1.2.1整数1.2.2小数 1.3二进制转换1.3.1 B->O1.3.2 B->H 1.4真值&机器数1.5 BCD码1.6 ASCII码1.7汉字与GBK1.8 UTF1.9检错码1.9.1奇偶校验码1.9.2循环冗余检测CRC1.…...

汇编语言中的艺术:数据压缩与解压缩技术
标题:汇编语言中的艺术:数据压缩与解压缩技术 数据压缩是计算机科学中的一项基本技术,它通过减少数据的冗余来降低存储或传输所需的空间。在低级语言如汇编语言中实现数据压缩和解压缩,不仅是一种技术挑战,也是对硬件…...

【Alibaba Cola 状态机】重点解析以及实践案例
【Alibaba Cola 状态机】重点解析以及实践案例 1. 状态模式 状态模式是一种行为型设计模式,允许对象在内部状态改变时改变其行为,简单地讲就是,一个拥有状态的context对象,在不同状态下,其行为会发生改变。看起来是改…...

购买商城源码前需要考虑哪些方面?
前言 购买商城源码前需要考虑的方面包括功能满足、技术兼容性、可扩展性、公司实力、客户评价、安全性与稳定性等。 购买商城源码是一项重要决策,需要综合考虑多个因素。以下是详细的考虑方面: 1.功能满足: 确保所选的源码能够支持企业所…...

MongoDB快速入门CRUD
1. 数据库管理 1.1 切换数据库 切换到名为 myDatabase 的数据库。如果该数据库不存在,MongoDB 会在第一次写入数据时自动创建它。 use myDatabase;1.2 查看当前数据库 显示当前使用的数据库的名称。 db; 1.3 显示所有数据库 列出当前 MongoDB 实例中的所有数…...