零基础STM32单片机编程入门(三十二) 4乘4矩阵键盘介绍及实战源码

一.概要

在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,8个I/O口就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加1个I/O口就可以构成20键的键盘,而直接用端口线则只能多出1键(总共9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

本文介绍了4*4矩阵按键,以及用STM32单片机实现矩阵按键数字输入。

在这里插入图片描述

二.4*4矩阵按键原理图

4*4矩阵按键的原理就是通过8个端口与单片机连接,4个IO口控制行,4个IO口控制列。
在这里插入图片描述

在这里插入图片描述

三.4*4矩阵按键代码驱动原理

如下图所示:

A0,A1,A2,A3接单片机的PA0,PA1,PA2,PA3脚,单片机这几个脚配置成输出。

A4,A5,A6,A7接单片机的PA4,PA5,PA6,PA7脚,单片机这几个脚配置成输入,并且管脚上拉,这样没有按键按下,A0脚输出低电平,没有导通,从A4脚读到的电平是高电平。假如K1按键按下,A0脚输出低电平就能从A4读到低电平,接下去A0输出高,然后依次A1,A2,A3先输出低,再输出高循环,假如下一个循环A2输出低的时候,A4读到低电平,那就是K9按键按下了。如果在A2输出低的时候,A5读到低电平,那就是K10按键按下了。
在这里插入图片描述

四.STM32单片机4*4矩阵按键实验

用杜邦线连接板子与OLED液晶:
板子G----液晶GND
板子3.3–液晶VCC
板子B8—液晶D0
板子B9—液晶D1
板子B12–液晶RES
板子B13–液晶DC
板子B14–液晶CS

用杜邦线连接板子与键盘模块:
开发板PA0<->模块R1
开发板PA1<->模块R2
开发板PA2<->模块R3
开发板PA3<->模块R4
开发板PA4<->模块C1
开发板PA5<->模块C2
开发板PA6<->模块C3
开发板PA7<->模块C4

在这里插入图片描述

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述

GPIO配置
在这里插入图片描述

配置系统主频
在这里插入图片描述
配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述
添加代码
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

主要程序:

uint8_t Key_row[1]={0xff};   //保存按键行扫描情况的状态数组
uint8_t key_Data;

/***
 *函数名:KEY_ROW_SCAN
 *功  能:按键行扫描
 *返回值:1~4,对应1~4行按键位置
 */
char KEY_ROW_SCAN(void)
{
    //读出行扫描状态
    Key_row[0] = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4)<<3;//列1读取
    Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)<<2);//列2读取
    Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)<<1);//列3读取
    Key_row[0] = Key_row[0] | (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7));//列4读取
    
    if(Key_row[0] != 0x0f)         //行扫描有变化,判断该列有按键按下
    {
      HAL_Delay(10);                    //消抖
      if(Key_row[0] != 0x0f)
        {   
                switch(Key_row[0])
                {
                    case 0x07:         //0111 判断为该列第1行的按键按下
                        return 1;
                    case 0x0b:         //1011 判断为该列第2行的按键按下
                        return 2;
                    case 0x0d:         //1101 判断为该列第3行的按键按下
                        return 3;
                    case 0x0e:         //1110 判断为该列第4行的按键按下
                        return 4;
                    default :
                        return 0;
                }
        }
        else return 0;
    }
    else return 0;
}

/***
 *函数名:KEY_SCAN
 *功  能:4*4按键扫描
 *返回值:0~16,对应16个按键
 */
char KEY_SCAN(void)
{    
    char Key_Num=0;       //1-16对应的按键数
    char key_row_num=0;        //行扫描结果记录
    
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);	//行1置低
    if( (key_row_num=KEY_ROW_SCAN()) != 0 )
    { 
        while(KEY_ROW_SCAN() != 0);  //消抖
        Key_Num = 0 + key_row_num;
    
    }
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);	//行1置高
    
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);	//行2置低       
    if( (key_row_num=KEY_ROW_SCAN()) != 0 )
    { 
        while(KEY_ROW_SCAN() != 0);
        Key_Num = 4 + key_row_num;
    }
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);	//行2置高
    
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);	//行3置低     
    if( (key_row_num=KEY_ROW_SCAN()) != 0 )
    { 
        while(KEY_ROW_SCAN() != 0);
    Key_Num = 8 + key_row_num;
    }
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);	//行3置高
    
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);	//行4置低    
    if( (key_row_num=KEY_ROW_SCAN()) != 0 )
    {
        while(KEY_ROW_SCAN() != 0);
        Key_Num = 12 + key_row_num;

    }
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);	//行4置高  
    
    return Key_Num;
}

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//8M外部晶振,72M系统主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();			       //初始化OLED  
	OLED_Clear(); 
	OLED_ShowCHinese(34,0,0);//光
	OLED_ShowCHinese(52,0,1);//子
	OLED_ShowCHinese(70,0,2);//物
	OLED_ShowCHinese(88,0,3);//联
	OLED_ShowString(36,3,"KEY TEST");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		key_Data = KEY_SCAN();
		if(key_Data!=0)
		{
			OLED_ShowNum(48,6,key_Data,3,16);//显示数字
		}
  }
  /* USER CODE END 3 */
}

五.CubeMX工程源代码下载

通过百度网盘分享的文件:32.4乘4矩阵键盘.rar
链接:https://pan.baidu.com/s/174j9-_OOCh2lOwJjmdwpvg
提取码:eryb

如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

CSDN代码下载

六.小结

矩阵键盘主要应用在需要使用大量按键的场景中,‌以节省IO资源。‌矩阵键盘通过将按键排列成矩阵形式,‌可以有效地减少I/O口的占用,‌适用于计算器、‌遥控器、‌触摸屏ID产品、‌银行的提款机、‌密码输入器等多种设备。‌

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值