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

news2024/11/25 20:40:05

为了实现计算器键盘,需要使用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.coloradmin.cn/o/1903964.html

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

相关文章

如何屏蔽搜索结果特定网站?无限添加指定域名屏蔽解决方案

如何通过Chrome插件屏蔽某网站的搜索结果 在使用搜索引擎时,有时我们会希望屏蔽掉某些不想看到的网站。那么,我们可以通过安装油猴(Tampermonkey)插件,并使用特定脚本来实现这个目的。由于Chrome网上应用店可能无法打…

数据结构之“队列”(全方位认识)

🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:数据结构 前言 上期博客介绍了” 栈 “这个数据结构,他具有先进后出的特点。本期介绍“ 队列 ”这个数据结构,他具有先进先出的特点。 目录…

ASCII码对照表【2024年汇总】

🍺ASCII相关文章汇总如下🍺: 🎈ASCII码对照表(255个ascii字符汇总)🎈🎈ASCII码对照表(Unicode 字符集列表)🎈🎈ASCII码对照表&#x…

Linux内核链表使用方法

简介: 链表是linux内核中最简单,同时也是应用最广泛的数据结构。内核中定义的是双向链表。 linux的链表不是将用户数据保存在链表节点中,而是将链表节点保存在用户数据中。linux的链表节点只有2个指针(pre和next),这样的话&#x…

中国星坤连接器:定制化服务,精准选型!

在当今快速发展的电子行业中,连接器作为电子设备中不可或缺的组成部分,其性能和品质直接影响到整个系统的性能表现。中国星坤连接器以其卓越的产品选型系统和质量保证,为全球客户提供了一站式的解决方案。 精准选型,快速定位 中国…

模板进阶:非类型模板参数,类模板特化,模板的编译分离

1. 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常…

【python】python母婴数据分析模型预测可视化(数据集+论文+PPT+源码)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

vue-cli 脚手架详细介绍

4 vue-cli 脚手架 1 脚手架介绍 vue-cli也叫vue脚手架,vue-cli是vue官方提供的一个全局命令工具,这个命令可以帮助我们快速的创建一个vue项目的基础架子。 脚手架:搭建好的一个架子,我们在架子上进行开发 开箱即用零配置基于webpack、webpac…

13 学习总结:指针 · 其一

目录 一、内存和地址 (一)内存 (二)内存单元 (三)地址 (四)拓展:CPU与内存的联系 二、指针变量和地址 (一)创建变量的本质 (二…

【MySQL】逻辑架构与存储引擎

一、逻辑架构 1、MySQL逻辑架构 我们可以根据上图来对sql的执行过程进行分析 第一步:客户端与服务器建立一个连接,从连接池中分配一个线程处理SQL语句第二步:SQL接口接受SQL指令第三步:如果是5.7版本,就会先去缓存中…

SpringMVC(2)——controller方法参数与html表单对应

controller方法参数与html表单对应 0. User实体类 import org.springframework.format.annotation.DateTimeFormat;import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Map;public class User implements Serializable {private …

期末考试结束,老师该如何私发成绩?

随着期末考试的落幕,校园里又恢复了往日的宁静。然而,对于老师们来说,这并不意味着工作的结束,相反,一系列繁琐的任务才刚刚开始。 成绩单的发放,就是其中一项让人头疼的工作。家长们焦急地等待着孩子的考试…

【全面讲解如何安装Jupyter Notebook!】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

springboot三层架构详细讲解

目录 springBoot三层架构0.简介1.各层架构1.1 Controller层1.2 Service层1.3 ServiceImpl1.4 Mapper1.5 Entity1.6 Mapper.xml 2.各层之间的联系2.1 Controller 与 Service2.2 Service 与 ServiceImpl2.3 Service 与 Mapper2.4 Mapper 与 Mapper.xml2.5 Service 与 Entity2.6 C…

【Spring Boot】关系映射开发(三):多对多映射

关系映射开发(三):多对多映射 1.创建实体1.1 创建 Student 实体1.2 创建 Teacher 实体 2.创建测试 在 多对多 关联关系中,只能通过 中间表 的方式进行映射,不能通过增加外键来实现。 注解 ManyToMany 用于关系的发出端…

【React Native优质开源项目】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

Nacos架构设计

Nacos1.X架构设计 Nacos2.X架构修改

Gitlab代码管理工具安装配置

前言: 没有真正的证书与域名建议使用httpip的方式在内网使用,不建议使用假的域名地址 一、安装前配置 #更改主机域名 hostnamectl set-hostname gitlab.dome.com bash #配置hosts 底部添加下面内容 vim /etc/hosts ############################ ip gi…

昇思25天学习打卡营第19天|Diffusion扩散模型

学AI还能赢奖品?每天30分钟,25天打通AI任督二脉 (qq.com) Diffusion扩散模型 本文基于Hugging Face:The Annotated Diffusion Model一文翻译迁移而来,同时参考了由浅入深了解Diffusion Model一文。 本教程在Jupyter Notebook上成…

【嵌入式DIY实例-ESP8266篇】-LCD ST7735显示BMP280传感器数据

LCD ST7735显示BMP280传感器数据 文章目录 LCD ST7735显示BMP280传感器数据1、硬件准备与接线2、代码实现本文介绍如何将 ESP8266 NodeMCU 板 (ESP-12E) 与 Bosch Sensortec 的 BMP280 气压和温度传感器连接。 NodeMCU 微控制器 (ESP8266EX) 从 BMP280 传感器读取温度和压力值,…