4×4矩阵键盘详解(STM32)

news2024/9/21 5:43:03

目录

一、介绍

二、传感器原理

1.原理图

2.工作原理介绍

三、程序设计

main.c文件

button4_4.h文件

button4_4.c文件

四、实验效果 

五、资料获取

项目分享


一、介绍

        ​​​​​矩阵键盘,又称为行列式键盘,是用4I/O线作为行线,4I/O线作为列线组成的键盘。在行线和列线的每一个交叉点上设置一个按键,因此键盘中按键的个数是4×4这种行列式键盘结构能够有效地提高单片机系统I/O口的利用率,节约单片机的资源。(8引脚控制16按键

哔哩哔哩视频:

4×4矩阵键盘详解(STM32)

(资料分享见文末) 

二、传感器原理

1.原理图

在硬件上,4条行线连接到微控制器的输出引脚,而4条列线连接到微控制器的输入引脚,每个按键位于行线和列线的交叉点上

2.工作原理介绍

    行线的主要功能是向列线发送扫描信号。当某一行线被设置为低电平时,与之相交的列线会被检测(若相对应的按键被按下,列线被检测为低电平)以判断是否有按键被按下。

通过依次将每一行线设置为低电平(可以逐行扫描键盘)。当检测到列线上有低电平时,可以确定被按下的按键位于当前选中的行上。若列线上无低电平,那么将此行线设置为高电平,下一行设置为低电平,进行新一轮按键检测。

三、程序设计

1.使用STM32F103C8T6读取4×4矩阵键盘采集的按键数据,通过串口发送至电脑

2.将读取得到按键信息数据同时在OLED上显示

BUTTON_1

PA0

BUTTON_2

PA1

BUTTON_3

PA2

BUTTON_4

PA3

BUTTON_1

PA4

BUTTON_2

PA5

BUTTON_3

PA6

BUTTON_4

PA7

main.c文件

#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "button4_4.h"

/*****************辰哥单片机设计******************
											STM32
 * 项目			:	4×4矩阵键盘实验                     
 * 版本			: V1.0
 * 日期			: 2024.9.5
 * MCU			:	STM32F103C8T6
 * 接口			:	参看button4_4.h							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥 

**********************BEGIN***********************/

u16 value;

int main(void)
{ 
	
  SystemInit();//配置系统时钟为72M	
	delay_init(72);
	LED_Init();
	LED_On();
	Button4_4_Init();
	
	OLED_Init();
	delay_ms(1000);
	
	OLED_Clear();
	//显示“按键:”
	OLED_ShowChinese(0,0,0,16,1);
	OLED_ShowChinese(16,0,1,16,1);
	OLED_ShowChar(40,0,':',16,1);
	

  while (1)
  {
		
		value = Button4_4_Scan();
		if(value!=0)
		{
			OLED_ShowNum(60,0,value,2,16,1);
			LED_Toggle();
			delay_ms(500);
		}
		else
			OLED_ShowString(60,0,"    ",16,1);
  }
}

button4_4.h文件

#ifndef __BUTTON4_4_H
#define	__BUTTON4_4_H
#include "stm32f10x.h"
#include "delay.h"
#include "math.h"

/*****************辰哥单片机设计******************
											STM32
 * 文件			:	4×4矩阵键盘h文件                   
 * 版本			: V1.0
 * 日期			: 2024.9.5
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥

**********************BEGIN***********************/

/***************根据自己需求更改****************/
// 4×4矩阵键盘 GPIO宏定义

#define		BUTTON_GPIO_CLK											RCC_APB2Periph_GPIOA
#define 	BUTTON_ROW1_GPIO_PORT								GPIOA
#define 	BUTTON_ROW1_GPIO_PIN							  GPIO_Pin_0	
#define 	BUTTON_ROW2_GPIO_PORT								GPIOA
#define 	BUTTON_ROW2_GPIO_PIN								GPIO_Pin_1
#define 	BUTTON_ROW3_GPIO_PORT								GPIOA
#define 	BUTTON_ROW3_GPIO_PIN								GPIO_Pin_2
#define 	BUTTON_ROW4_GPIO_PORT								GPIOA
#define 	BUTTON_ROW4_GPIO_PIN								GPIO_Pin_3

#define 	BUTTON_COL1_GPIO_PORT								GPIOA
#define 	BUTTON_COL1_GPIO_PIN								GPIO_Pin_4
#define 	BUTTON_COL2_GPIO_PORT								GPIOA
#define 	BUTTON_COL2_GPIO_PIN								GPIO_Pin_5
#define 	BUTTON_COL3_GPIO_PORT								GPIOA
#define 	BUTTON_COL3_GPIO_PIN								GPIO_Pin_6
#define 	BUTTON_COL4_GPIO_PORT								GPIOA
#define 	BUTTON_COL4_GPIO_PIN								GPIO_Pin_7

	
/*********************END**********************/

void Button4_4_Init(void);
int Button4_4_Scan(void);


#endif

button4_4.c文件

#include "button4_4.h"

/*****************辰哥单片机设计******************
											STM32
 * 文件			:	4×4矩阵键盘c文件                   
 * 版本			: V1.0
 * 日期			: 2024.9.5
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥

**********************BEGIN***********************/

struct IO_PORT
{                                            
        GPIO_TypeDef *GPIO_x;                 
        unsigned short GPIO_pin;
};
static struct IO_PORT KEY_OUT[4] = {
        {BUTTON_ROW1_GPIO_PORT, BUTTON_ROW1_GPIO_PIN},
				{BUTTON_ROW2_GPIO_PORT, BUTTON_ROW2_GPIO_PIN},
        {BUTTON_ROW3_GPIO_PORT, BUTTON_ROW3_GPIO_PIN}, 
				{BUTTON_ROW4_GPIO_PORT, BUTTON_ROW4_GPIO_PIN}
};
static struct IO_PORT KEY_IN[4] = {
        {BUTTON_COL1_GPIO_PORT, BUTTON_COL1_GPIO_PIN}, 
				{BUTTON_COL2_GPIO_PORT, BUTTON_COL2_GPIO_PIN},
        {BUTTON_COL3_GPIO_PORT, BUTTON_COL3_GPIO_PIN}, 
				{BUTTON_COL4_GPIO_PORT, BUTTON_COL4_GPIO_PIN}
};
unsigned char key[4][4];

void Button4_4_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    unsigned char i;
	
//    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 

    RCC_APB2PeriphClockCmd(BUTTON_GPIO_CLK, ENABLE);      

		for(i=0;i<4;i++)
	{
		GPIO_InitStructure.GPIO_Pin = KEY_OUT[i].GPIO_pin;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		
		GPIO_Init(KEY_OUT[i].GPIO_x, &GPIO_InitStructure);
	}
	
	for(i=0;i<4;i++)
	{
		GPIO_InitStructure.GPIO_Pin = KEY_IN[i].GPIO_pin;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		
		GPIO_Init(KEY_IN[i].GPIO_x, &GPIO_InitStructure);
	}
  	

	for(i = 0; i < 4; i++)
	{
		GPIO_SetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin);
	}
}
int Button4_4_Scan(void)
{
        unsigned char i, j;
        for(i = 0; i < 4; i++)            
        {
          delay_ms(5);
					GPIO_ResetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin);   
          for(j = 0; j < 4; j++)            
          {
                  delay_ms(5); 
						      if(GPIO_ReadInputDataBit(KEY_IN[j].GPIO_x, KEY_IN[j].GPIO_pin) == 0)
                   {
                                key[i][j] = 1;
                   }else{
                                key[i][j] = 0;
                   }
          }
          GPIO_SetBits(KEY_OUT[i].GPIO_x, KEY_OUT[i].GPIO_pin);
        }
        if(key[0][0]==1)return 13;
        else if(key[0][1]==1)return 14;
        else if(key[0][2]==1)return 15;
        else if(key[0][3]==1)return 16;
        else if(key[1][0]==1)return 9;
        else if(key[1][1]==1)return 10;
        else if(key[1][2]==1)return 11;
        else if(key[1][3]==1)return 12;
        else if(key[2][0]==1)return 5;
        else if(key[2][1]==1)return 6;
        else if(key[2][2]==1)return 7;
        else if(key[2][3]==1)return 8;
        else if(key[3][0]==1)return 1;
        else if(key[3][1]==1)return 2;
        else if(key[3][2]==1)return 3;
        else if(key[3][3]==1)return 4;
				
				else return 0;
				    
}

四、实验效果 

五、资料获取

项目分享

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

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

相关文章

【四范式】浅谈NLP发展的四个范式

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是计算机科学&#xff0c;人工智能&#xff0c;语言学关于计算机和人类自然语言之间的相互作用的领域&#xff0c;是计算机科学领域与人工智能领域中的一个重要方向。NLP发展到今天已经进入到了…

[Python学习日记-19] 细讲数据类型——集合

[Python学习日记-19] 细讲数据类型——集合 简介 集合的创建 集合的增删查 集合的循环 集合的去重 集合的关系运算 简介 在前面我们学习到了列表、元组、字符串、字典这几种数据类型&#xff0c;在 Python 中还有最后一种数据类型&#xff0c;那就是集合&#xff0c;下面…

Cloudflare Pages 部署 Next.js 应用教程

Cloudflare Pages 部署 Next.js 应用教程 本教程将指导你如何将现有的 Next.js 应用部署到 Cloudflare Pages。 准备工作 安装部署依赖 首先,安装 cloudflare/next-on-pages: npm install --save-dev cloudflare/next-on-pages添加 wrangler.toml 配置文件 在项目根目录创建 …

如何删除git提交记录

今天在提交github时&#xff0c;不小心提交了敏感信息&#xff0c; 不要问我提交了啥&#xff0c;问就是不知道 查了下资料&#xff0c;终于找到简单粗暴的方式来删除提交记录。方法如下 git reset --soft HEAD~i i代表要恢复到多少次提交前的状态&#xff0c;如指定i 2&…

GD32F4开发 -- SEGGER RTT移植

FreeRTOS移植了&#xff0c;我将SEGGER RTT移植和FATFS也一并移植进去得了。 参看&#xff1a;GD32F4开发 – JLink使用 这里面其实已经讲了怎么移植了。 一、移植 直接将整个 RTT 文件夹加入工程 将其拷贝到我的工程&#xff1a; 二、创建 RTT 分组 工程目录如下&#xf…

微波无源器件 功分器2 用于双极化应用的新型宽带圆波导四路功分

摘要&#xff1a; 提出了一种适用于多级()波束形成网络高度紧凑和有效的双模功。圆波导双极化通过使用一个对称4:1的十字转门拓扑和有策略的腔体谐振抑制器来实现理论35dB的交叉极化隔离的高于20%的带宽。对于一个Ku波段(10.5-13GHz)的双模四路功分器的实测验证被提出了&#x…

2024重症医学科常用评估量表汇总,附操作步骤与评定标准!

常笑医学整理了8个重症医学科常用的评估量表&#xff0c;包括院前指数评估、多脏器功能障碍评分、急性生理学与慢性健康状况评分等。这些量表在常笑医学网均支持在线评估、下载和创建项目使用。 01 院前指数评估 &#xff08;完整量表请点击量表名称查看&#xff09; 院前指数…

音频芯片DP7344兼容CS4344低成本方案双通道24位DA转换器

产品简介 DP7344 是一款完整的 2 通道输出数模转换芯片&#xff0c;内含插值滤波器、Multi-Bit 数模转换器、输出模拟滤波器&#xff0c;并支持大部分的音频数据格式。 DP7344 基于一个带线性模拟低通滤波器的四阶 Multi-BitΔ∑调制器&#xff0c;自动检测信号频率和主时钟频率…

班组建设中如何避免团队协作的问题?

在班组建设的广阔天地里&#xff0c;团队协作无疑是推动项目进展、提升工作效率的基石。然而&#xff0c;在实际操作中&#xff0c;团队协作往往伴随着一系列复杂而微妙的问题&#xff0c;这些问题若得不到妥善解决&#xff0c;便会成为阻碍团队前进的绊脚石。本文&#xff0c;…

AMD CMD UMD CommonJs ESM 的历史和区别

这几个东西都是用于定义模块规范的。有些资料会提及到这些概念&#xff0c;不理清楚非常容易困惑。 ESM&#xff08;ES Module&#xff09; 这个实际上我们是最熟悉的&#xff0c;就是ES6的模块功能。出的最晚&#xff0c;因为是官方出品&#xff0c;所以大势所趋&#xff0c…

Qt 开发:深入详解 Qt 的信号与槽机制——彻底搞懂QT信号与槽

一、概念 Qt 的信号与槽&#xff08;Signals and Slots&#xff09;机制是一个用于对象间通信的核心特性。这个机制使得对象能以松散耦合的方式进行通信&#xff0c;从而提升了代码的模块化和可维护性。 信号&#xff08;Signal&#xff09;&#xff1a;对象状态的变化或事件…

C++:内部类,匿名对象,操作符new与delete

一.内部类 1.如果一个类定义在另一个类的内部&#xff0c;这个内部类就叫做内部类。内部类是一个独立的类&#xff0c;跟定义在全局相比&#xff0c;他只是受外部类类域限制和访问限定符限制&#xff0c;所以外部类定义的对象中不包含内部类。 2.内部类默认是外部类的友元类。…

基于Java+Mysql实现(web)大型企业管理系统

技术报告 第一章 系统概述 包括用户管理、权限管理、软件项目管理、软件模块管理、测试用例管理、测试任务分配、bug管理等功能。实现公司不同部门间团队协作&#xff0c;管理人员也能够更加有效的把控系统开发的进度。 本实验综合应用JavaWeb编程中的Servlet&#xff0c;JS…

【渗透测试】-CVE-2016-4437-Shiro550漏洞复现

Shiro550漏洞爆出的时间是2016年为第4437个漏洞&#xff0c;所以它的CVE编码是2016-4437 文章目录 前言 什么是Shiro550漏洞&#xff1f; 1.Shiro550漏洞原理&#xff1a; 2.漏洞利用 3.漏洞复现&#xff1a; 前提&#xff1a;下载并打开vulhub靶场。 CVE-2016-4437-shiro550漏…

CentOS 7停更官方yum源无法使用,更换阿里源

CentOS 7官方源已经停止维护&#xff0c;导致无法使用yum更新软件。通过尝试使用阿里云、清华大学等第三方源解决&#xff0c;现以阿里云第三方源进行配置&#xff1a; 1、备份原有的yum源配置文件 # cp -a /etc/yum.repos.d /etc/yum.repos.d.bak 2、删除原有的yum源配置文…

什么是交换机级联?

在现代计算机网络中&#xff0c;交换机级联是一种广泛应用的技术&#xff0c;有助于提升网络的扩展性和灵活性。本文将深入探讨交换机级联相关知识&#xff0c;详细介绍其基本概念和连接配置方法&#xff0c;并对常见技术问题进行解答。 交换机级联概述 交换机级联是指通过将…

windows server2012 配制nginx安装为服务的时候,直接跳要安装.net框架,用自动的安装,直接失败的解决。

1、上一个已成功在安装过程中的图&#xff1a; 2、之前安装过程中错误的图&#xff1a; 3、离线安装解决&#xff1a; 下载.net framework 3.5&#xff0c;然后解压后&#xff0c;选择指定备用源路径&#xff0c;然后选择.net安装包所在目录&#xff1a; 只要指定上面全路径就…

WebGL系列教程八(GLSL着色器基础语法)

目录 1 前言2 基本原则3 基本数据类型4 顶点着色器和片元着色器4.1 声明4.2 初始化项目4.3 赋值 5 结构体5.1 声明5.2 赋值 6 函数6.1 基本结构6.2 自定义函数6.3 常用内置函数 7 精度8 其他9 总结 1 前言 通过前七讲&#xff0c;我们已经见过了WebGL中的部分基础语法&#xff…

初始爬虫1(补充)

TCP 和 UDP 是什么&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff09;都是传输层协议&#xff0c;它们负责在计算机网络上发送和接收数据包。两者有不同的特性和适用场景&#xff1a; TCP&#xff0…

文档团队如何组成?

经常有朋友问我文档团队是由怎样背景的人组成的&#xff1f;今天来聊聊这个话题。 中国贸促会和技术传播专委会以及lnfomagic学院2023年在技术传播行业做了一个调查&#xff0c;在收到的231份有效样本中显示&#xff0c; 受访群体的背景主要是两大类&#xff0c;他们分别是技术…