STM32--按键矩阵--扫描法

一、按键矩阵原理

1.原理图

在这里插入图片描述

2.原理图讲解

按键矩阵其实是通过八根引脚来检测按下按键,常规按键一个按键对应一个引脚口的输入,而按键矩阵通过8根引脚,4根为输入模块,4根为输出模式,输出模块式依次输出,输入模式依次扫描,从而确定按键矩阵按下的按键所处位置,从而节省引脚资源的使用,理论上来说按键矩阵做的越多按键,引脚资源的利用率越高,但是正常来说也没人会用到36键啥的按键吧哈哈哈哈哈哈哈。所以4X4的按键矩阵用的是最广泛的。
在这里插入图片描述

二、按键矩阵实现思路

实现思路很简单,用到了扫描法去扫描按键矩阵的四根输入引脚,四根输出引脚依次输出高电平。从而确定按下按键的位置,为了方便后面的二次开发,设置了全局结构体变量去保存这次扫描按键是否有检测到按键按下,按下的行,列位置和将按键转换成1到16的数值按下的是哪个数值,整体的难度不大,但是写起来有点繁琐,接来下上代码,源码链接我会放在下面有想要下载来二次开发的可以去下载看看哈,没有的也可以自己根据下面部分代码去实现大家想要的功能。

三、按键矩阵实现代码

main.c

/*
	项目功能:按键矩阵按下通过串口发送按下的行、列、位数到调试助手
	时间:2022.05.04
	作者:嘻嘻子的呢
	项目设备:STM32F103C8T6、按键矩阵、USB转TTL
	项目接线:
		USB转TTL
			PA9	---- RX
			PA10---- TX
		按键矩阵:
			COL:
				PA1--COL1
				PA2--COL2
				PA3--COL3
				PA4--COL4
			ROW:
				PB1--ROW1
				PB2--ROW2
				PB3--ROW3
				PB4--ROW4
*/

int main(void)
{
    
    	
	//系统功能,设备,硬件初始化
	delay_init();
	NVIC_Configuration();
	USARTX_Init(USART1, 115200);
	KEY_MATRIX_Init();
	while(1) 
	{
    
    		
		KEY_MATRIX_Scan();
		if(xKEY_MATRIX.res_flag == 1)		
			printf("按下第 %d 行 \t 第 %d 列 \t 第 %d 个按键\r\n",xKEY_MATRIX.res_row,xKEY_MATRIX.res_col,xKEY_MATRIX.res);
	}	  
	
}

key_matrix.h


/*****************************************************************************
 ** 声明 全局变量
****************************************************************************/
typedef struct {
    
    
	GPIO_TypeDef* 	GPIOx;	//所用的GPIO端口
	uint16_t 		Pinx;	//所用的Pin引脚	
}GPIO_GROUP;

typedef struct 
{
    
    
	uint8_t 	res_flag;			// 检测结果  0:没有按下	1:有按下
	uint8_t 	res_row;			// 第几行
	uint8_t		res_col;			// 第几列
	uint8_t		res;				// 1-16 	从左到右从上到下
}xKEY_MATRIX_TypeDef;

extern xKEY_MATRIX_TypeDef xKEY_MATRIX;

/*****************************************************************************
 ** 声明  全局函数
****************************************************************************/
void KEY_MATRIX_Init(void);	// 按键矩阵初始化函数

void KEY_MATRIX_Scan(void);	// 按键矩阵扫描函数

key_matrix.c


static void KEY_ROW_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
static void KEY_COL_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

//控制某行电压
static void Activate_ROW(uint8_t row, uint8_t status);
//按键矩阵全部行的电压全部设置
static void Activate_ALL_ROW(uint8_t status);
/******************************************************************************
 * 函  数: KEY_MATRIX_Init
 * 功  能: 按键矩阵初始化    
 * 参  数: 无
 ******************************************************************************/  
void KEY_MATRIX_Init(void)
{
    
    
	u8 i = 0;
	//开启时钟
	RCC_APB2PeriphClockCmd(KEY_MATRIX_APB2PERIPH,ENABLE);	
	
	//配置引脚
	//KEY ROW  	推挽输出电压
	for(i = 0; i < 4; i++) 	KEY_ROW_Init(GPIO_KEY_ROW[i].GPIOx, GPIO_KEY_ROW[i].Pinx);
	
	//KEY COL	下拉输入
	for(i = 0; i < 4; i++)	KEY_COL_Init(GPIO_KEY_COL[i].GPIOx, GPIO_KEY_COL[i].Pinx);
}



/******************************************************************************
 * 函  数: Activate_ROW
 * 功  能: 按键矩阵行电压变化
 * 参  数: 无
 ******************************************************************************/ 
void Activate_ROW(uint8_t row, uint8_t status)
{
    
    
	if (status) 	GPIO_SetBits(GPIO_KEY_ROW[row].GPIOx, GPIO_KEY_ROW[row].Pinx);
	else 			GPIO_ResetBits(GPIO_KEY_ROW[row].GPIOx, GPIO_KEY_ROW[row].Pinx);
}

/******************************************************************************
 * 函  数: Activate_ROW
 * 功  能: 按键矩阵全部行电压一起变化
 * 参  数: 无
 ******************************************************************************/ 
void Activate_ALL_ROW(uint8_t status)
{
    
    
	int row;
	for (row = 0; row < 4; row++) 		Activate_ROW(row, status);
}

/******************************************************************************
 * 函  数: KEY_MATRIX_Scan
 * 功  能: 从按键矩阵中读取按下按键的位置数据       
 * 参  数: 无
 * 说  明: 调用后,获取到的数据,保存到结构体xKEY_MATRIX中
 ******************************************************************************/  
void KEY_MATRIX_Scan(void)
{
    
    
	u8 row = 0,col = 0;
	//所有行电平置零复位
	Activate_ALL_ROW(0);
	//结构体res_flag清零
	xKEY_MATRIX.res_flag = 0;
	//每行电压变化 每次电压变化完检查列是否有读取到电压
	//当读取到的时候即按键按下
	for(row = 0; row < 4 ; row++)
	{
    
    
		//行电压变化
		Activate_ROW(row, 1);
		delay_ms(1);
		for(col = 0; col < 4; col++)
		{
    
    
			//检测到高电平
			if(GPIO_ReadInputDataBit(GPIO_KEY_COL[col].GPIOx,GPIO_KEY_COL[col].Pinx) == 1)
			{
    
    
				// 结构体赋值
				xKEY_MATRIX.res_flag = 1;
				xKEY_MATRIX.res_row = row + 1;
				xKEY_MATRIX.res_col = col + 1;
				xKEY_MATRIX.res = row * 4 + col + 1;
			} 
		}
		Activate_ROW(row, 0);
	}
	//所有行电平置零复位
	Activate_ALL_ROW(0);
}

以上就是关于按键矩阵的源码展示啦,有需要下面链接下载哈,因为下载积分好像会动态的调整吧,如果觉得不着急的,可以下面留下邮箱或者私聊我哈,我发你也可以的,大家互相学习交流呀。

源文件链接

https://download.csdn.net/download/qq_45488746/85284058

猜你喜欢

转载自blog.csdn.net/qq_45488746/article/details/124574634