STM32f4日记7之外设矩阵键盘的使用(4X4矩阵键盘解放板上资源)

STM32f4日记7之外设矩阵键盘的使用(4X4矩阵键盘解放板上资源)
板子:stm32f407zgt6正点原子迷你版
鉴于目前网上的教学形态各异,很多带有迷惑、误导性质,所以写这篇文章交流自己的看法,也权当纪录自己的学习经历。

作者:shawn
可咨询QQ:965798711(要完整代码可在评论区留下邮箱)
2021.2.13(大年初二)
19:05
All rights reserved

//
如果你觉得对你有帮助,请点赞同,这对我很重要,谢谢。
//
一、器材介绍
核心模块:4X4矩阵键盘
在这里插入图片描述
原理图如下:
在这里插入图片描述
二、原理讲解
扎实学过51单片机的朋友一定对矩阵键盘了解的多一些,但是对于一开始就入手STM32的朋友,矩阵键盘可能是个难点,我简单介绍一下(用不规范的语言)。
就用这张原理图来说:
在这里插入图片描述
矩阵键盘16个按键,一共被8根线连接P30,P31,P32,P33连接四行,P34,P35,P36,P37连接四列。
首先我们将P30,P31,P32,P33初始化为输入IO,将P34,P35,P36,P37初始化为输出IO
举个栗子:如果我们按下S1
先给P30高电平,此时我们检测P34,P35,P36,P37发现P34高电平

再给P31高电平,此时我们检测P34,P35,P36,P37发现都是低电平

再给P32高电平,此时我们检测P34,P35,P36,P37发现都是低电平

再给P33高电平,此时我们检测P34,P35,P36,P37发现都是低电平

此时,我们就确定了,跟P34,P30有关的那个按键就是被按下的按键,此时就是S1,这就是俗称的矩阵键盘的扫描
其他的几个按键以此类推,会发现每一个按键对应的两根线都是独一无二的。
三、硬件连接
我们是用PF的2,3,4,5 IO口跟PC的0,1,2,3 IO口(PF输出,PC输入)
按照上面给出的那个矩阵键盘的图:
PF的2,3,4,5 IO口对应R1,2,3,4。
PC的0,1,2,3 对应C1,2,3,4。
四、代码编写
key.c
里面两个函数void KEY_Init(void) 用来配置底层
u8 KEY_Scan(void)用来矩阵键盘检测

#include "key.h"
#include "sys.h" 
#include "usart.h"

u8 tem;
void KEY_Init(void) 
{
    
     
 GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOF,ENABLE);
 
	GPIO_InitStructure.GPIO_Pin  =      GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);//输入
 
 
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOF, &GPIO_InitStructure);//输出 
}
 
 
u8 KEY_Scan(void)
{
    
    	
	static u8 key_flag1=1,key_flag2=1,key_flag3=1,key_flag4=1;     
	u8 KeyVal;
  GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0004));	//0100     1111 1111 1100 0011  检测第一行
	if(key_flag1&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
	{
    
    
		 key_flag1=0;
		     if (Read_Lie1==1){
    
     KeyVal= 1; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie2==1) {
    
    KeyVal= 2; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie3==1) {
    
    KeyVal= 3; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie4==1) {
    
    KeyVal= 4; printf("key:%d\r\n",KeyVal);}
	}
	else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag1=1;
	else return 0;
	
 
		GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0008));//1000检测第二行
	if(key_flag2&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
	{
    
    
		 key_flag2=0;
		     if (Read_Lie1==1){
    
     KeyVal= 5; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie2==1) {
    
    KeyVal= 6; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie3==1) {
    
    KeyVal= 7; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie4==1) {
    
    KeyVal= 8; printf("key:%d\r\n",KeyVal);}
	}
	else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag2=1;
	else return 0;
	
	GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0010));//   0001  0000检测第三行
	if(key_flag3&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
	{
    
    
		key_flag3=0;
		     if (Read_Lie1==1){
    
     KeyVal= 9; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie2==1) {
    
    KeyVal= 10; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie3==1) {
    
    KeyVal= 11; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie4==1) {
    
    KeyVal= 12; printf("key:%d\r\n",KeyVal);}
	}
	else if(Read_Lie1==0&&Read_Lie2==0&&Read_Lie3==0&&Read_Lie4==0)key_flag3=1;
	else return 0;
	
	
				
	 GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0020));//0010 0000检测第四行
   if(key_flag4&&(Read_Lie1==1||Read_Lie2==1||Read_Lie3==1||Read_Lie4==1))
	 {
    
    
		 key_flag4=0;
		     if (Read_Lie1==1){
    
     KeyVal= 13; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie2==1) {
    
    KeyVal= 14; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie3==1) {
    
    KeyVal= 15; printf("key:%d\r\n",KeyVal);}
		else if (Read_Lie4==1) {
    
    KeyVal= 16; printf("key:%d\r\n",KeyVal);}
	 }
	 else if(Read_Lie1==0 &&Read_Lie2==0 &&Read_Lie3==0 &&Read_Lie4==0 )key_flag4=1;
	 else return 0;
	 return KeyVal;
 
}

GPIO_Write(GPIOF,(( GPIOF->ODR & 0xFFC3 )|0x0008));这是位操作,划重点 ,大家理解一下
key.h里面

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"
 
#define Read_Lie1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)
#define Read_Lie2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)
#define Read_Lie3 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
#define Read_Lie4 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
 
 
void KEY_Init(void);
u8 KEY_Scan(void);  	
#endif

主函数里面循环KEY_Scan()就行
五、实验效果
打开串口依次按键就能看到数据
在这里插入图片描述
六、其实打比赛输入显示可以合为一体
使用串口屏
可以看我之前发过的文章STM32f4日记4之HMI智能串口屏与单片机串口通信实验
点上面链接就行

作者:shawn
可咨询QQ:965798711(要完整代码可在评论区留下邮箱)
2021.2.13(大年初二)
19:05
All rights reserved

猜你喜欢

转载自blog.csdn.net/qq_51564898/article/details/113802558