STM32CubeMX实现4X5矩阵按键(HAL库实现)

为了实现计算器键盘,需要使用4X5矩阵按键,因此,我在4X4矩阵键盘上重新设计了一个4X5矩阵按键。原理图如下:

原理描述:

4X5矩阵按键,可以设置4个引脚为输出,5个引脚为输入模式,4个引脚依次设置为低电平,5个引脚依次扫描读取电平变化,如果为低电平,则表示按键按下,这样就可以通过坐标算出按键的位置(二维矩阵坐标)。

设计的PCB板如下:

3D效果图如下:

实物图:

接线表如下:

矩阵按键

STM32

R5

PA15

上拉输入模式

R4

PB12

上拉输入模式

R3

PB13

上拉输入模式

R2

PB14

上拉输入模式

R1

PB15

上拉输入模式

C1

PA8

推挽输出模式

C2

PA9

推挽输出模式

C3

PA10

推挽输出模式

C4

PA11

推挽输出模式

-

PA2

USART2_TX

-

PA3

USART2_RX

功能:

        将按键的信息在串口2显示,和博客原理一致:

4X4矩阵按键实现,博客地址:

STM32CubeMX实现矩阵按键(HAL库实现)_使用hal库使用矩阵按键-CSDN博客

CubeMX配置过程如下:

注意:这里需要注意一下,如果用STM32F103C8T6最小系统USB供电,PA12口不能作为普通的输入输出口,因为该口与USB相接,导致电平混乱。

代码如下:

按键扫描:

/* USER CODE BEGIN 0 */
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(GPIOA, ROW5_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 4\r\n", 8, 0XFFFF);return 20;}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(GPIOA, ROW5_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 4\r\n", 8, 0XFFFF);return 19;}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(GPIOA, ROW5_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 4\r\n", 8, 0XFFFF);return 18;}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(GPIOA, ROW5_Pin)){HAL_Delay(20);if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin)){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);}while(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, ROW5_Pin));//HAL_UART_Transmit(&huart2, (uint8_t *)"key: 4\r\n", 8, 0XFFFF);return 17;}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;
}
/* USER CODE END 0 */

主函数:

int main(void)
{/* USER CODE BEGIN 1 */uint16_t keyValue = 0;		//	按键返回的键值uint8_t str[10] = "";/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_GPIO_WritePin(GPIOA, COL1_Pin|COL2_Pin|COL3_Pin|COL4_Pin, GPIO_PIN_SET);	//	初始化高电平/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if((keyValue = keyScan()) !=0 ){sprintf((char*)str,"key: %d\r\n",keyValue);HAL_UART_Transmit(&huart2, str, strlen((char*)str), 0XFFFF);}}/* USER CODE END 3 */
}

实现效果,如下:

代码并不是很复杂。

代码如下:

STM32CubeMX实现4X5矩阵按键(HAL库实现)资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【云原生】Prometheus监控Docker指标并接入Grafana

目录 一、前言 二、docker监控概述 2.1 docker常用监控指标 2.2 docker常用监控工具 三、CAdvisor概述 3.1 CAdvisor是什么 3.2 CAdvisor功能特点 3.3 CAdvisor使用场景 四、CAdvisor对接Prometheus与Grafana 4.1 环境准备 4.2 docker部署CAdvisor 4.2.2 docker部署…

【Java探索之旅】初识多态_概念_实现条件

文章目录 📑前言一、多态1.1 概念1.2 多态的实现条件 🌤️全篇总结 📑前言 多态作为面向对象编程中的重要概念,为我们提供了一种灵活而强大的编程方式。通过多态,同一种操作可以应用于不同的对象,并根据对象…

el-table 树形数据与懒加载 二级数据不展示

返回的数据中 children和hasChildren只能有一个,不能同时存在,否则加载数据会失败

零基础STM32单片机编程入门(八)定时器PWM输入实战含源码视频

文章目录 一.概要二.PWM输入框架图三.CubeMX配置一个PWM输入例程1.硬件准备2.创建工程3.调试 四.CubeMX工程源代码下载五.讲解视频链接地址六.小结 一.概要 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用单…

手把手搭建微信机器人,帮你雇一个24小时在线的个人 AI 助理(上)

上一篇,带领大家薅了一台腾讯云服务器:玩转云服务:手把手带你薅一台腾讯云服务器,公网 IP。 基于这台服务器,今天我们一起动手捏一个基于 LLM 的微信机器人。 0. 前置准备 除了自己常用的微信账号以外,还…

盘点8款国内顶尖局域网监控软件(2024年国产局域网监控软件排名)

局域网监控软件对于企业网络管理至关重要,它们可以帮助IT部门维护网络安全,优化网络性能,同时监控和控制内部员工的网络使用行为。以下是八款备受推崇的局域网监控软件,每一款都有其独特的优势和适用场景。 1.安企神软件 试用版领…

VSCode远程服务器如何上传下载文件(超方便!)

方法一: 1、在VSCode应用商店安装SFTP插件 2、然后就可以直接把文件拖进VSCode即可,如下图所示: 这里的目录是我远程服务器上的目录,可以直接将要上传的文件直接拖进需要的文件夹 3、如果要从远程服务器上下载文件到本地&#x…

安装Gradle

官网文档 https://gradle.org/ 腾讯下载镜像:https://mirrors.cloud.tencent.com/gradle/ 文档:https://docs.gradle.org/current/userguide/userguide.html 命令行文档:https://docs.gradle.org/current/userguide/command_line_interface.…

Java高级重点知识点-21-IO、字节流、字符流、IO异常处理、Properties中的load()方法

文章目录 IOIO的分类 字节流字节输出流【OutputStream】字节输入流【InputStream】图片复制 字符流字符输入流【FileReader】字符输出流【FileWriter】 IO异常的处理(扩展知识)Properties属性集(java.util) IO Java中I/O操作主要是指使用 java.io 包下的…

《侃侃而谈 · 关于接外单的一些事》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

期末成绩发布方式

期末考试结束后,成绩单的发放总是让老师们头疼不已。想象一下,每个学生的成绩都需要老师一个个私信给家长,不仅耗时耗力,而且极易出错。 在传统的成绩单发放方式中,老师往往需要通过电子邮件、短信或者微信等方式&…

【Rust基础入门】Hello Cargo

文章目录 前言Cargo是什么?Cargo的作用查看cargo版本使用cargo创建项目Cargo.toml文件cargo build命令cargo runcargo check为发布构建 总结 前言 在Rust编程中,Cargo扮演着至关重要的角色。它是Rust的包管理器,负责处理许多任务&#xff0c…

【TB作品】51单片机 Proteus仿真 00002仿真-智能台灯色调倒计时光强

实验报告:基于51单片机的智能台灯控制系统 背景 本实验旨在设计一个基于51单片机的智能台灯控制系统,该系统可以通过按键进行手动控制,并能根据环境光强度自动调节台灯亮度。此外,系统还具备倒计时关灯功能。 器件连接 51单片…

软件运维服务方案(Word原件2024)

软件运维服务方案(Word原件) 1. 服务简述 我们提供全面的软件运维服务,确保软件系统的稳定运行。 1.1 服务内容 包括监控、维护、故障排查与优化。 1.2 服务方式 结合远程与现场服务,灵活响应客户需求。 1.3 服务要求 高效响应&am…

双向DFS——AcWing 171. 送礼物

双向DFS 定义 双向深度优先搜索(Bi-directional Depth First Search, BD-DFS)是一种在图或树中寻找两点间路径的算法。与传统的单向DFS不同,BD-DFS同时从起始节点和目标节点出发进行搜索,使用两个DFS过程。一个向前探索从起点到…

从一个(模型设计的)想法到完成模型验证的步骤

从有一个大型语言模型(LLM)设计的想法到完成该想法的验证,可以遵循以下实践步骤: 需求分析: 明确模型的目的和应用场景。确定所需的语言类型、模型大小和性能要求。分析目标用户群体和使用环境。 文献调研&#xff1a…

swiftui中常用组件picker的使用,以及它的可选样式

一个可选项列表就是一个picker组件搞出来的,它有多个样式可以选择,并且可以传递进去一些可选数据,有点像前端页面里面的seleted组件,但是picker组件的样式可以更多。可以看官方英文文档:PickerStyle | Apple Developer…

【对接支付宝支付详细流程】

下面示例使用的是支付宝的网页支付,最终的效果如图: 1.前置条件 对接支付宝你需要了解的知识点 1.加密算法 对称加密和非对称加密,RSA2加密算法,签名验证 2.支付宝平台openid unionId的概念 https://opendocs.alipay.com/pre…

文件管理下:文件函数的学习

前言 Hello,小伙伴们你们的作者君又来了,上次我们简单介绍了文件的坐拥并简单提到了数据的读取,和C语言的默认流的作用,今天我将继续带领大家探索文件的奥秘,大家准别好了吗? 在内容开始之前还是按照惯例&#xff0c…

初识java—jdk17的一些新增特性

文章目录 前言一 : yield关键字二 :var关键字三 :密封类四 :空指针异常:五:接口中的私有方法:六:instanceof关键字 前言 这里介绍jdk17相对于jdk1.8的部分新增特性。 一 &#xff…