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;
				    
}

四、实验效果

五、资料获取

项目分享

相关推荐
linweidong14 小时前
嵌入式电机:如何在低速和高负载状态下保持FOC(Field-Oriented Control)算法的电流控制稳定?
stm32·单片机·算法
Zero_Era14 小时前
高性价比安全MCU——LKT6830C
单片机·嵌入式硬件·安全
国科安芯15 小时前
卫星通讯导航FPGA供电单元DCDC芯片ASP4644S2B可靠性分析
单片机·嵌入式硬件·fpga开发·架构·安全性测试
jllws116 小时前
硬件_键盘是如何工作的(一)
计算机外设·硬件
知南x16 小时前
【STM32MP157 视频监控项目】(2) 移植 Nginx
stm32·nginx·音视频
一碗姜汤16 小时前
【统计基础】卡尔曼滤波,矩阵对迹求导,Joseph Form,条件数
线性代数·矩阵
sunfove17 小时前
麦克斯韦方程组 (Maxwell‘s Equations) 的完整推导
线性代数·算法·矩阵
易水寒陈17 小时前
单片机实现的工厂模式
单片机
yyy(十一月限定版)17 小时前
matlab矩阵的操作
算法·matlab·矩阵
ComputerInBook18 小时前
代数学基本概念理解——幺正矩阵(Unitary matrix)(酉矩阵?)
线性代数·矩阵·正交矩阵·幺正矩阵·酉矩阵