嵌入式进阶——矩阵键盘
🎬 秋野酱:《个人主页》
🔥 个人专栏:《Java专栏》《Python专栏》
⛺️心若有所向往,何惧道阻且长
文章目录
- 矩阵按键
- 原理图
- 按键状态检测
- 单行按键状态检测
- 多行按键状态检测
- 状态记录
- 状态优化
- 循环优化
矩阵按键
矩阵键盘是一种常见的数字输入设备,由多行多列的按键组成。每个按键都有一个唯一的行列坐标,通过行列坐标可以确定按键的编号,从而实现对数字或字母的输入。
原理图

矩阵键盘的基本结构包括按键、行引脚和列引脚。按键一般是机械按键或触摸按键,行引脚和列引脚分别与矩阵键盘的行和列相连,用于检测按键的输入状态。
按键状态检测
单个按键状态检测

● 输出端的电平
● 输入端的状态
● 按键抬起
通过按键抬起时的状态,我们分析输入端的电平信号,来确定抬起时输入端的默认电平状态。

通过按键按下时的状态,我们分析输入端的电平信号,来确定按下时输入端的默认电平状态。
通过分析确认,默认输出端和输入端都是高电平;
● 当输出端输出低电平时,输入端为高电平,则开关为抬起状态;
● 当输出端输出低电平时,输入端为低电平,则开关为按下状态;
单行按键状态检测

通过逐一检测输入端的状态,来判断按键是否按下。
多行按键状态检测

首先,将第一行输出低电平,其余行设置为高电平。目的是为了只测试第一行的按键状态。

然后,将第二行输出低电平,其余行设置为高电平。目的是为了只测试第二行的按键状态。

接着,将第三行输出低电平,其余行设置为高电平。目的是为了只测试第三行的按键状态。

最后,将第四行输出低电平,其余行设置为高电平。目的是为了只测试第四行的按键状态。
状态记录
通过自定义状态来记录按键状态
// 记录16个按键状态,0为按下,1为抬起
u16 key_state = 0xFFFF;......void scan() {
// 初始都是 高电平ROW_COL_RESET();NOP1();// ROW1// 给 row1 低电平,读取COL1的值ROW1 = 0;NOP1();// 当前是UP,当之前是DOWN,则为UP// 当前是DOWN,当之前是UP,则为DOWN if(COL1 != (key_state & 0x01) >> 0) {if(COL1) {// 修改当前状态为UPkey_state |= 0x01;printf("K1 Up\r\n");} else {// 修改当前状态为DOWNkey_state &= ~0x01;printf("K1 Down\r\n");}}......
}
状态优化
通过define优化一些数值的操作,方便在后续看代码时方便理解,提高代码的阅读性。
// 记录16个按键状态,0为按下,1为抬起
u16 key_state = 0xFFFF;#define KEY_UP 1
#define KEY_DOWN 0
// 第n个按键的状态
#define KEY_STATE(n) ((key_state & (1 << n)) >> n)
#define SET_KEY_UP(n) (key_state |= (1 << n))
#define SET_KEY_DOWN(n) (key_state &= ~(1 << n))#define ROW_COL_RESET() {ROW1=1,ROW2=1,ROW3=1,ROW4=1;COL1=1,COL2=1,COL3=1,COL4=1;}......void scan() {// 初始都是 高电平ROW_COL_RESET();NOP1();// ROW1// 给 row1 低电平,读取COL1的值ROW1 = 0;NOP1();// 当前是UP,当之前是DOWN,则为UP// 当前是DOWN,当之前是UP,则为DOWNif(COL1 != KEY_STATE(0)) {if(COL1) {// 修改当前状态为UPSET_KEY_UP(0);printf("K1 Up\r\n");} else {// 修改当前状态为DOWNSET_KEY_DOWN(0);printf("K1 Down\r\n");}}......
}
循环优化
操作的按键众多,通过循环的方式来操控每一个按键,减少代码量,方便维护。
#define ROW 4
#define COL 4// 记录16个按键状态,0为按下,1为抬起
u16 key_state = 0xFFFF;#define KEY_UP 1
#define KEY_DOWN 0
// 第n个按键的状态
#define KEY_STATE(r, c) ((key_state & (1 << (r * ROW + c))) >> (r * ROW + c))
#define SET_KEY_UP(r, c) (key_state |= (1 << (r * ROW + c)))
#define SET_KEY_DOWN(r, c) (key_state &= ~(1 << (r * ROW + c)))#define ROW_COL_RESET() {ROW1=1,ROW2=1,ROW3=1,ROW4=1;COL1=1,COL2=1,COL3=1,COL4=1;}void scan() {u8 i, j;for(i = 0; i < ROW; i++) {// 初始都是 高电平ROW_COL_RESET();NOP1();ROW_ON(i);for(j = 0; j < COL; j++) {// 当前是UP,当之前是DOWN,则为UP// 当前是DOWN,当之前是UP,则为DOWNif(COL_STATE(j) != KEY_STATE(i, j)) {if(COL_STATE(j)) {// 修改当前状态为UPSET_KEY_UP(i, j);printf("(%d, %d) Up\r\n", (int)i, (int)j);} else {// 修改当前状态为DOWNSET_KEY_DOWN(i, j);printf("(%d, %d) Down\r\n", (int)i, (int)j);}}}}
}
相关文章:
嵌入式进阶——矩阵键盘
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 矩阵按键原理图按键状态检测单行按键状态检测多行按键状态检测 状态记录状态优化循环优化 矩阵按键 矩阵键盘是一种常见的数字输入…...
请说出vue.cli项目中src目录每个文件夹和文件的用法
在Vue CLI项目中,src目录是存放项目源码及需要引用的资源文件的主要位置。以下是src目录下常见文件夹和文件的用法: components 用途:存放可重用的Vue组件。这些组件通常用于在多个页面或布局中共享UI和功能。特点:组件应该是模块…...
【MySQL精通之路】InnoDB磁盘I/O和文件空间管理(11)
主博客: 【MySQL精通之路】InnoDB存储引擎-CSDN博客 目录 1.InnoDB磁盘I/O 1.1 预读 1.2 双写缓冲区 2.文件空间管理 2.1 Pages, Extents, Segments, and Tablespaces(很重要) 2.2 配置保留文件段页面的百分比 2.3 页与表行的关系 …...
基于springboot+html的二手交易平台(附源码)
基于springboothtml的二手交易平台 介绍部分界面截图如下联系我 介绍 本系统是基于springboothtml的二手交易平台,数据库为mysql,可用于毕设或学习,附数据库 部分界面截图如下 联系我 VX:Zzllh_...
正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-24.3,4 SPI驱动实验-I.MX6U SPI 寄存器
前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…...
【Pandas】数据处理方法
1.数据拆分 pandas.Series.str.extract() Series.str.extract(pat, flags0, expandTrue)[source]extract(提取) 参数 pat: 带分组的正则表达式。 flag: re模块中的标志,例如re.IGNORECASE,修改正则表达式匹配的大小写、空格等 expand: 默认为True&…...
【ArcGIS For JS】前端geojson渲染行政区划图层并加标签
原理 通过DataV工具 生成行政区的geojson(得到各区的面元素数据), 随后使用手动绘制featureLayer与Label,并加载到地图。 //vue3加载geojson数据public/geojson/pt.json,在MapView渲染上加载geojson数据 type是"MultiPolygon"fetc…...
Spring AOP原理详解:动态代理与实际应用
1. Spring AOP概述 1.1 什么是AOP AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在将横切关注点(Cross-Cutting Concerns)从业务逻辑中分离出来。横切关注点是指那些分散在应用程序多…...
死锁的四个必要条件
死锁的四个必要条件如下: 互斥条件(Mutual Exclusion):资源是独占的,即在同一时间内一个资源只能被一个进程或线程所使用,其他进程或线程无法访问该资源。 请求与保持条件(Hold and Wait&#…...
源网络地址转换SNAT
左上角的是访问互联网发送的数据包,第一个是访问,第二个是网页传回来的 3、4项是源端口号和目的端口号(3是随机的(1024-65535),那个是http的网页服务端口就是80) 那么往回传数据的时候源和目的…...
【算法】平衡二叉搜索树的左旋和右旋
树旋转是一种维护平衡树结构的重要操作,主要用于平衡二叉搜索树(如AVL树和红黑树)。树旋转分为左旋和右旋。 1. 树旋转的定义 左旋 (Left Rotation) 左旋操作将节点及其右子树进行调整,使其右子树的左子节点成为根节点…...
介绍Django Ninja框架
文章目录 安装快速开始特性详解自动文档生成定义请求和响应模型异步支持中间件支持测试客户端 结论 Django Ninja是一个基于Python的快速API开发框架,它结合了Django和FastAPI的优点,提供了简单易用的方式来构建高性能的Web API。 安装 使用以下命令安…...
使用uniapp内置组件checkbox-group所遇到的问题
checkbox-group属性说明 属性名类型默认值说明changeEventHandle <checkbox-group> 中选项发生改变触发change事件 detail { value:[选中的checkbox的value的数组] } 问题代码 <checkbox-group change"handleEVent()"><view style&qu…...
嵌入式学习记录5.23(超时检测、抓包分析)
目录 一.自带超时参数的函数 1.1 select函数 1.2 poll函数的自带超时检测参数 二、不带超时检测参数的函数 三、通过信号完成时间的设置 四、更新下载源 五、wireshark使用 5.1. 安装 5.2. wireshark 抓包 5.2.1 wireshark与对应的OSI七层模型 编辑5.2.2 包头分析 …...
Linux|如何在 awk 中使用流控制语句
引言 当您从 Awk 系列一开始回顾我们迄今为止介绍的所有 Awk 示例时,您会注意到各个示例中的所有命令都是按顺序执行的,即一个接一个。但在某些情况下,我们可能希望根据某些条件运行一些文本过滤操作,这就是流程控制语句的方法。 …...
OceanBase数据库诊断调优,与高可用架构——【DBA从入门到实践】第八期
在学习了《DBA从入门到实践》的前几期课程后,大家对OceanBase的安装部署、日常运维、数据迁移以及业务开发等方面应当已经有了全面的认识。若在实际应用中遇到任何疑问或挑战,欢迎您在OceanBase社区问答论坛中交流、讨论。此次,《DBA从入门到…...
LLVM技术在GaussDB等数据库中的应用
目录 LLVM和数据库 LLVM适用场景 LLVM对所有类型的SQL都会有收益吗? LLVM在OLTP中就一定没有收益吗? GaussDB中的LLVM 1. LLVM在华为应用于数据库的时间线 2. GaussDB LLVM实现简析 3. GaussDB LLVM支持加速的场景 支持LLVM的表达式:…...
【SQL学习进阶】从入门到高级应用(三)
文章目录 ✨条件查询✨条件查询语法格式✨等于、不等于✨等于 ✨不等于 <> 或 ! ✨大于、大于等于、小于、小于等于✨大于 >✨大于等于 >✨小于 <✨小于等于 < ✨and✨or✨and和or的优先级问题✨between...and... 🌈你好呀!我是 山顶风…...
迷你手持小风扇哪个品牌续航强?五款强续航迷你手持小风扇推荐!
夏天就俩字儿:热和空调!太阳大得让人想躲,一出汗,感觉全身毛孔都在喊“太热啦”!这时空调简直是救命恩人啊,热得只想赖在屋里不出来。但出门总得面对大太阳,一出门就哗哗流汗。所以,…...
SpringBoot 微服务中怎么获取用户信息 token
SpringBoot 微服务中怎么获取用户信息 token 当我们写了一个A接口,这个接口需要调用B接口,但是B接口需要包含请求头内容,比如需要用户信息、用户id等内容,由于不在同一个线程中,使用ThreadLocal去获取数据是无法获取的…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
