基于STM32F103——矩阵按键+串口打印

STM32F103-矩阵按键+串口打印

基本介绍

最近做了一个门禁卡小玩意,用到了4X4矩阵按键,在这里也单独的记录一下。
矩阵按键图
在这里插入图片描述
思路:
矩阵按键读取键值写法多样,有一行一行的检测,也有是全部行检测,我这里是全部去扫。
先扫描4列是否有按下,有 再切换 扫描所有行。

第一步:先让行拉低(输出模式),去检测列(输入模式 拉高)
			如果检测到有
第二步:让列拉低(输出模式), 去检测行(输入模式 拉高)
第三步:这样就可以获取到哪按键按下了。

代码

matrix_key.c

#include "matrix_key.h"
#include "usart.h"

uint8_t key_flag;		



/*4X4矩阵按键的表盘设置*/
const uint8_t matrix_key_tab[4][4] =
{
    
    
	'1', '2', '3', 'A',
	'4', '5', '6', 'B',
	'7', '8', '9', 'C',
	'*', '0', '#', 'D',
};




/***********************************************************************
描述: 按键 列 设置输入模式(前4个)
************************************************************************/
void key_set_list_input_mode(void)
{
    
    
	GPIO_InitTypeDef KEY_InitStruction;
	RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
	
	//列引脚
	KEY_InitStruction.GPIO_Pin   = KEY5_PIN | KEY6_PIN | KEY7_PIN | KEY8_PIN;	//引脚
	KEY_InitStruction.GPIO_Mode  = GPIO_Mode_IPU; 								//上拉输入	
	GPIO_Init(KEY_PORT, &KEY_InitStruction);
	
}


/***********************************************************************
描述: 按键 列 设置输出模式
************************************************************************/
void key_set_list_output_mode(void)
{
    
    
	GPIO_InitTypeDef KEY_InitStruction;
	RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
	
	//列引脚
	KEY_InitStruction.GPIO_Pin   = KEY5_PIN | KEY6_PIN | KEY7_PIN | KEY8_PIN;	//引脚
	KEY_InitStruction.GPIO_Mode  = GPIO_Mode_Out_PP; 							//推挽输出	
	KEY_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;							//速率
	
	GPIO_Init(KEY_PORT, &KEY_InitStruction);
}




/***********************************************************************
描述: 按键 行 设置输入模式
************************************************************************/
void key_set_row_input_mode(void)
{
    
    
	GPIO_InitTypeDef KEY_InitStruction;
	RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
	
	//列引脚
	KEY_InitStruction.GPIO_Pin   = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;	//引脚
	KEY_InitStruction.GPIO_Mode  = GPIO_Mode_IPU; 								//上拉输入	
	GPIO_Init(KEY_PORT, &KEY_InitStruction);
}


/***********************************************************************
描述: 按键 行 设置输出模式
************************************************************************/
void key_set_row_output_mode(void)
{
    
    
	GPIO_InitTypeDef KEY_InitStruction;
	RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);
	
	//列引脚
	KEY_InitStruction.GPIO_Pin   = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;	//引脚
	KEY_InitStruction.GPIO_Mode  = GPIO_Mode_Out_PP; 							//推挽输出	
	KEY_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;							//速率
	
	GPIO_Init(KEY_PORT, &KEY_InitStruction);

}


/***********************************************************************
描述: 按键初始化函数 
************************************************************************/
void matrix_key_init(void)
{
    
    	
	ROW_OUT_MODE;		//行设置输出模式
	LIST_INT_MODE;		//列设置输入模式
}


/***********************************************************************
描述: 获取键值 函数
返回: 返回表盘对应键值
************************************************************************/
uint8_t matrix_key_scanf(void)
{
    
    
	static uint8_t key_status;	
	uint8_t R,L;
	uint8_t key_temp;
	
	//检测列 所以我们让行拉低 列拉高
	LIST_INT_MODE;	LIST_SET_HIGH;
	ROW_OUT_MODE;	ROW_SET_LOW;
	
	key_temp = ~GPIO_ReadInputData(KEY_PORT) & 0XF0;
	if(key_temp == 0) {
    
    key_status = 0; return 0;}
	
	//第一次检测到
	if(key_status == 0)
	{
    
    
		key_status = 1;	
		return 0;
	}
	//第二次检测到
	else if(key_status == 1)
	{
    
    
		key_status = 2;
		
		//读取列
		switch(key_temp)
		{
    
    
			case 0x10:	L = 0;	break;
			case 0x20:	L = 1;	break;
			case 0x40:	L = 2;	break;
			case 0x80:	L = 3;	break;		
			default:	return 0;
		}
		//快速转换模式 
		//再检测行是否有按键按下 所以先让列拉低 行拉高
		LIST_OUT_MODE;	LIST_SET_LOW;	//PA4 ~ PA7
		ROW_INT_MODE;	ROW_SET_HIGH;	//PA0 ~ PA3

		key_temp = ~GPIO_ReadInputData(KEY_PORT) & 0X0F;
		//读取行
		switch(key_temp)
		{
    
    
			
			case 0x01:	R = 0;	break;
			case 0x02:	R = 1;	break;
			case 0x04:	R = 2;	break;
			case 0x08:	R = 3;	break;
			default:	return 0;
		}

		return matrix_key_tab[R][L];;
	}
	//证明没松开按键
	else if(key_status == 2)
	{
    
    
		return 0;
	}
	key_status = 0;
	return 0;

}



/***********************************************************************
描述: 矩阵键盘处理 函数
************************************************************************/
void matrix_key_process(void)
{
    
    
	uint8_t key_val;
	
	if(key_flag)
	{
    
    
		key_flag = 0;
		key_val = matrix_key_scanf();			//获取键值
		if(key_val == 0) return;	
		printf("KEY:%c\r\n",key_val);
	}	
}


matrix_key.h

#ifndef __MATRIX_KEY_H
#define __MATRIX_KEY_H
#include "stm32f10x.h"

#define 	KEY_RCC			RCC_APB2Periph_GPIOA		//时钟
#define 	KEY_PORT		GPIOA						//端口


#define 	KEY1_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY1_PORT		GPIOA						//端口
#define 	KEY1_PIN		GPIO_Pin_0					//引脚

#define 	KEY2_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY2_PORT		GPIOA						//端口
#define 	KEY2_PIN		GPIO_Pin_1					//引脚

#define 	KEY3_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY3_PORT		GPIOA						//端口
#define 	KEY3_PIN		GPIO_Pin_2					//引脚

#define 	KEY4_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY4_PORT		GPIOA						//端口
#define 	KEY4_PIN		GPIO_Pin_3					//引脚

#define 	KEY5_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY5_PORT		GPIOA						//端口
#define 	KEY5_PIN		GPIO_Pin_4					//引脚

#define 	KEY6_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY6_PORT		GPIOA						//端口
#define 	KEY6_PIN		GPIO_Pin_5					//引脚

#define 	KEY7_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY7_PORT		GPIOA						//端口
#define 	KEY7_PIN		GPIO_Pin_6					//引脚

#define 	KEY8_RCC		RCC_APB2Periph_GPIOA		//时钟
#define 	KEY8_PORT		GPIOA						//端口
#define 	KEY8_PIN		GPIO_Pin_7					//引脚


#define		ROW_INT_MODE	key_set_row_input_mode()
#define		ROW_OUT_MODE	key_set_row_output_mode()

#define		LIST_INT_MODE	key_set_list_input_mode()
#define		LIST_OUT_MODE	key_set_list_output_mode()

#define 	LIST_SET_HIGH	{
      
      GPIO_SetBits(KEY_PORT,KEY5_PIN);GPIO_SetBits(KEY_PORT,KEY6_PIN);GPIO_SetBits(KEY_PORT,KEY7_PIN);GPIO_SetBits(KEY_PORT,KEY8_PIN);}
#define 	LIST_SET_LOW	{
      
      GPIO_ResetBits(KEY_PORT,KEY5_PIN);GPIO_ResetBits(KEY_PORT,KEY6_PIN);GPIO_ResetBits(KEY_PORT,KEY7_PIN);GPIO_ResetBits(KEY_PORT,KEY8_PIN);}

#define 	ROW_SET_HIGH	{
      
      GPIO_SetBits(KEY_PORT,KEY1_PIN);GPIO_SetBits(KEY_PORT,KEY2_PIN);GPIO_SetBits(KEY_PORT,KEY3_PIN);GPIO_SetBits(KEY_PORT,KEY4_PIN);}
#define 	ROW_SET_LOW		{
      
      GPIO_ResetBits(KEY_PORT,KEY1_PIN);GPIO_ResetBits(KEY_PORT,KEY2_PIN);GPIO_ResetBits(KEY_PORT,KEY3_PIN);GPIO_ResetBits(KEY_PORT,KEY4_PIN);}



extern const uint8_t key_tab[4][5];
extern uint8_t key_flag;



void key_set_list_input_mode(void);		//按键 列 设置输入模式
void key_set_list_output_mode(void);	//按键 列 设置输出模式
void key_set_row_input_mode(void);		//按键 行 设置输入模式
void key_set_row_output_mode(void);		//按键 行 设置输出模式

void matrix_key_init(void);		//按键初始化
uint8_t matrix_key_scanf(void);	//获取按键键值
void matrix_key_process(void);
#endif


main.c

#include "stm32f10x.h"
#include "timer.h"
#include "matrix_key.h"
#include "usart.h"

/*
接线:
4X4矩阵按键
行:	PA0 ~ PA3
列: PA4 ~ PA7
*/


int  main()
{
    
    

	usart1_init(115200);	//串口1初始化   用于输出键值
	matrix_key_init();		//矩阵按键初始化
	timer3_init();			//定时器3初始化 用于去检测按键

	while(1)
	{
    
    	
		matrix_key_process();	//矩阵按键检测和处理
	}  
}



项目演示

在这里插入图片描述

如果我哪里写的有问题,或者不好,请大家多多指教

#整个工程代码。
printf("+meQ:844797079\n")

如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈

继续加油!!!

猜你喜欢

转载自blog.csdn.net/weixin_47457689/article/details/125033164