当前位置: 首页 > news >正文

嵌入式进阶——矩阵键盘

🎬 秋野酱:《个人主页》
🔥 个人专栏:《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);}}}}
}
http://www.lryc.cn/news/356817.html

相关文章:

  • 请说出vue.cli项目中src目录每个文件夹和文件的用法
  • 【MySQL精通之路】InnoDB磁盘I/O和文件空间管理(11)
  • 基于springboot+html的二手交易平台(附源码)
  • 正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-24.3,4 SPI驱动实验-I.MX6U SPI 寄存器
  • 【Pandas】数据处理方法
  • 【ArcGIS For JS】前端geojson渲染行政区划图层并加标签
  • Spring AOP原理详解:动态代理与实际应用
  • 死锁的四个必要条件
  • 源网络地址转换SNAT
  • 【算法】平衡二叉搜索树的左旋和右旋
  • 介绍Django Ninja框架
  • 使用uniapp内置组件checkbox-group所遇到的问题
  • 嵌入式学习记录5.23(超时检测、抓包分析)
  • Linux|如何在 awk 中使用流控制语句
  • OceanBase数据库诊断调优,与高可用架构——【DBA从入门到实践】第八期
  • LLVM技术在GaussDB等数据库中的应用
  • 【SQL学习进阶】从入门到高级应用(三)
  • 迷你手持小风扇哪个品牌续航强?五款强续航迷你手持小风扇推荐!
  • SpringBoot 微服务中怎么获取用户信息 token
  • npm包-fflate
  • 华为WLAN无线组网技术与解决方案
  • 闲鱼电商运营高级课程,一部手机学会闲鱼开店赚钱
  • Yann LeCun 和 Elon Musk 就 AI 监管激烈交锋
  • C++重点基础知识汇总大全
  • 【Linux】线程安全及锁的使用
  • 深入解析绘图范式:面向对象与直接操作的较量
  • 英特尔LLM技术挑战记录
  • 在 MFC 中 UNICODE 加 _T 与 L 长字符串,有什么区别?
  • synopsys EDA 2016 合集 下载
  • CentOS 7如何使用systemctl管理应用