STM32CubeMX实现矩阵按键(HAL库实现)
功能描述:
实现矩阵按键验证,将矩阵按键的按键值,通过串口显示,便于后面使用。
实物图

原理图:

编程原理:
原理很简单,就是通过循环设置引脚为低电平,另外引脚扫描读取电平值,如果是低电平则表示按键按下,就是一个矩阵关系,这里直接将扫描代码分享给大家,使用最简单的思路实现。
接线表:
| 矩阵按键 | STM32 | 模式 |
| R4 | PB12 | 上拉输入模式 |
| R3 | PB13 | 上拉输入模式 |
| R2 | PB14 | 上拉输入模式 |
| R1 | PB15 | 上拉输入模式 |
| C1 | PA8 | 推挽输出模式 |
| C2 | PA9 | 推挽输出模式 |
| C3 | PA10 | 推挽输出模式 |
| C4 | PA11 | 推挽输出模式 |
| - | PA2 | USART2_TX |
| - | PA3 | USART2_RX |
cubeMX配置:

代码如下:
uint16_t keyScan(void)
{HAL_GPIO_WritePin(GPIOA, COL1_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, COL2_Pin|COL3_Pin|COL4_Pin, GPIO_PIN_SET);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 4\r\n", 8, 0XFFFF);return 4;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 8\r\n", 8, 0XFFFF);return 8;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 12\r\n", 9, 0XFFFF);return 12;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 16\r\n", 9, 0XFFFF);return 16;}HAL_GPIO_WritePin(GPIOA, COL2_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, COL1_Pin|COL3_Pin|COL4_Pin, GPIO_PIN_SET);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 3\r\n", 9, 0XFFFF);return 3;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 7\r\n", 9, 0XFFFF);return 7;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 11\r\n", 9, 0XFFFF);return 11;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 15\r\n", 9, 0XFFFF);return 15;}HAL_GPIO_WritePin(GPIOA, COL3_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, COL1_Pin|COL2_Pin|COL4_Pin, GPIO_PIN_SET);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 2\r\n", 9, 0XFFFF);return 2;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 6\r\n", 9, 0XFFFF);return 6;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 10\r\n", 9, 0XFFFF);return 10;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 14\r\n", 9, 0XFFFF);return 14;}HAL_GPIO_WritePin(GPIOA, COL4_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, COL1_Pin|COL2_Pin|COL3_Pin, GPIO_PIN_SET);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW4_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 1\r\n", 9, 0XFFFF);return 1;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW3_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 5\r\n", 9, 0XFFFF);return 5;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW2_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 9\r\n", 9, 0XFFFF);return 9;}if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOB, ROW1_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 13\r\n", 9, 0XFFFF);return 13;}return 0;
}
实现效果
如下:


源码链接:
STM32CubeMXHAL库实现矩阵按键资源-CSDN文库
吾心电子
相关文章:
STM32CubeMX实现矩阵按键(HAL库实现)
功能描述: 实现矩阵按键验证,将矩阵按键的按键值,通过串口显示,便于后面使用。 实物图 原理图: 编程原理: 原理很简单,就是通过循环设置引脚为低电平,另外引脚扫描读取电平值&…...
mmdetection3D指定版本安装指南
1. 下载指定版本号 选择指定版本号下载mmdetection3d的源码,如这里选择的是0.17.2版本 git clone https://github.com/open-mmlab/mmdetection3d.git -b v0.17.22. 安装 cd mmdetection3d安装依赖库 pip install -r requirment.txt编译安装 pip install -v e .…...
SQLMap工具详解与SQL注入防范
SQLMap工具详解与SQL注入防范 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨SQLMap工具的详细使用方法以及如何防范SQL注入攻击。 SQL注入简介 SQL注入是一种常见的安全漏洞&am…...
如何在Java中实现自定义数据结构:从头开始
如何在Java中实现自定义数据结构:从头开始 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Java中实现自定义数据结构ÿ…...
【机器学习】在【Pycharm】中的应用:【线性回归模型】进行【房价预测】
专栏:机器学习笔记 pycharm专业版免费激活教程见资源,私信我给你发 python相关库的安装:pandas,numpy,matplotlib,statsmodels 1. 引言 线性回归(Linear Regression)是一种常见的统计方法和机器学习算法&a…...
如何在 Linux 中后台运行进程?
一、后台进程 在后台运行进程是 Linux 系统中的常见要求。在后台运行进程允许您在进程独立运行时继续使用终端或执行其他命令。这对于长时间运行的任务或当您想要同时执行多个命令时特别有用。 在深入研究各种方法之前,让我们先了解一下什么是后台进程。在 Linux 中…...
软考-软件设计师
软考 软考科目 软考分为初级、中级、高级,初级含金量相对不够,高级考试有难度,所以大多数人都在考中级,中级也分很多科目,我考的是软件设计师(已经通过)。 合格标准 考试分为上午题和下午题…...
UOS系统中JavaFx笔锋功能
关于笔锋功能,网上找了很久,包括Java平台客户端,Android端,相关代码资料比较少,找了很多经过测试效果都差强人意,自己也搓不出来,在UOS平台上JavaFX也获取不到压力值,只能用速度的变…...
后端加前端Echarts画图示例全流程(折线图,饼图,柱状图)
本文将带领读者通过一个完整的Echarts画图示例项目,演示如何结合后端技术(使用Spring Boot框架)和前端技术(使用Vue.js或React框架)来实现数据可视化。我们将实现折线图、饼图和柱状图三种常见的数据展示方式ÿ…...
ValidateAntiForgeryToken、AntiForgeryToken 防止CSRF(跨网站请求伪造)
用途:防止CSRF(跨网站请求伪造)。 用法:在View->Form表单中: aspx:<%:Html.AntiForgeryToken()%> razor:Html.AntiForgeryToken() 在Controller->Action动作上:[ValidateAntiForge…...
《昇思25天学习打卡营第5天 | mindspore 网络构建 Cell 常见用法》
1. 背景: 使用 mindspore 学习神经网络,打卡第五天; 2. 训练的内容: 使用 mindspore 的 nn.Cell 构建常见的网络使用方法; 3. 常见的用法小节: 支持一系列常用的 nn 的操作 3.1 nn.Cell 网络构建&…...
SQLServer:从数据类型 varchar 转换为 numeric 时出错。
1.工作要求 计算某两个经纬度距离 2.遇到问题 从数据类型 varchar 转换为 numeric 时出错。 3.解决问题 项目版本较老,使用SQLServer 2012 计算距离需执行视图,如下: SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO ALTER view vi_ord…...
探索迁移学习:通过实例深入理解机器学习的强大方法
探索迁移学习:通过实例深入理解机器学习的强大方法 🍁1. 迁移学习的概念🍁2. 迁移学习的应用领域🍁2.1 计算机视觉🍁2.2 自然语言处理(NLP)🍁2.3 医学图像分析🍁2.4 语音…...
【Linux】性能分析器 perf 详解(四):trace
上一篇:【Linux】性能分析器 perf 详解(三) 1、trace 1.1 简介 perf trace 类似于 strace 工具:用于对Linux系统性能分析和调试的工具。 原理是:基于 Linux 性能计数器(Performance Counters for Linux, PCL),监控和记录系统调用和其他系统事件。 可以提供关于硬件…...
信息安全体系架构设计
对信息系统的安全需求是任何单一安全技术都无法解决的,要设计一个信息安全体系架构,应当选择合适的安全体系结构模型。信息系统安全设计重点考虑两个方面;其一是系统安全保障体系;其二是信息安全体系架构。 1.系统安全保障体系 安…...
GPT-5即将登场:AI赋能下的未来工作与日常生活新图景
随着OpenAI首席技术官米拉穆拉蒂在近期采访中的明确表态,GPT-5的发布已不再是遥不可及的梦想,而是即将在一年半后与我们见面的现实。这一消息无疑在科技界乃至全社会引发了广泛关注和热烈讨论。从GPT-4到GPT-5的飞跃,被形容为从高中生到博士生…...
RocketMQ实战:一键在docker中搭建rocketmq和doshboard环境
在本篇博客中,我们将详细介绍如何在 Docker 环境中一键部署 RocketMQ 和其 Dashboard。这个过程基于一个预配置的 Docker Compose 文件,使得部署变得简单高效。 项目介绍 该项目提供了一套 Docker Compose 配置,用于快速部署 RocketMQ 及其…...
前端项目vue3/React使用pako库解压缩后端返回gzip数据
pako仓库地址:https://github.com/nodeca/pako 文档地址:pako 2.1.0 API documentation 外部接口返回一个直播消息或者图片数据是经过zip压缩的,前端需要把这个数据解压缩之后才可以使用,这样可以大大降低网络数据传输的内容&…...
C++专业面试真题(1)学习
TCP和UDP区别 TCP 面向连接。在传输数据之前,通信双方需要先建立一个连接(三次握手)。可靠性。TCP提供可靠的数据传输,它通过序列号、确认应答、重传机制和校验和等技术确保数据的正确传输。数据顺序:TCP保证数据按发…...
2024 年人工智能和数据科学的五个主要趋势
引言 2023年,人工智能和数据科学登上了新闻头条。生成性人工智能的兴起无疑是这一显著提升曝光度的驱动力。那么,在2024年,该领域将如何继续占据头条,并且这些趋势又将如何影响企业的发展呢? 在过去几个月,…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
