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

目录

一、介绍

二、传感器原理

1.原理图

2.工作原理介绍

三、程序设计

main.c文件

button4_4.h文件

button4_4.c文件

四、实验效果

五、资料获取

项目分享


一、介绍

​​​​​矩阵键盘,又称为行列式键盘,是用4条I/O线作为行线,4条I/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文件

cpp 复制代码
#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文件

cpp 复制代码
#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文件

cpp 复制代码
#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;
				    
}

四、实验效果

五、资料获取

项目分享

相关推荐
析木不会编程1 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
云云3212 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3213 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
ThreeYear_s3 小时前
基于FPGA 的4位密码锁 矩阵键盘 数码管显示 报警仿真
fpga开发·矩阵·计算机外设
十年一梦实验室3 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
15年网络推广青哥3 小时前
国际抖音TikTok矩阵运营的关键要素有哪些?
大数据·人工智能·矩阵
阿正的梦工坊3 小时前
范德蒙矩阵(Vandermonde 矩阵)简介:意义、用途及编程应用
线性代数·矩阵
枯无穷肉5 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名6775 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件
嵌入式科普6 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长