嵌入式开发—矩阵键盘原理及程序设计

文章目录

  • 一、前言
    • 1、矩阵键盘是什么
    • 2、矩阵键盘的应用场景
    • 3、矩阵键盘的替代品
    • 3、矩阵键盘的优缺点
  • 二、矩阵键盘按键检测原理
    • 1、逐行逐列扫描法
    • 2、反线法
  • 三、矩阵键盘按键检测程序实现

一、前言

1、矩阵键盘是什么

矩阵键盘很好理解,就是排布类似矩阵的按键,大家可以想一下点阵的外形。大概长下面这个样子
矩阵键盘淘宝图

2、矩阵键盘的应用场景

矩阵键盘一般应用在需要用到大量按键的场景,主要是为了节省按键使用的IO资源。比如一个项目需要用到16个按键,如果使用普通的独立按键,每一个按键都需要一个IO,16个按键就需要16个IO。对于珍贵的IO资源看来说,只是为了实现简单的按键检测就占用那么多,实在是一种浪费。而如果将这16个按键换成一个4*4的矩阵键盘,只需要8根线就可以实现16个按键的检测,能够节省很多IO资源。

3、矩阵键盘的替代品

相比于矩阵按键,也可以采用一些编码器来实现,原理于矩阵键盘相同,都是给每一个按键对应一个固定位数的二进制数。只不过矩阵键盘需要软件自己检测每一个IO上的高低电平信息,得到一个二进制数。而利用编码器就是将这一步交给硬件实现,硬件会直接根据按键按下的位置自己产生一个固定位数的二进制数,软件直接检测二进制数即可。利用编码器实现的话软件方面会减少一些工作,检测起来更加方便,而且通过硬件直接输出二进制数比软件自己检测更加可靠。

3、矩阵键盘的优缺点

1)使用矩阵键盘优点在于可以用相对较少的IO实现多个按键的检测。
2)缺点也较为明显,如果有多个按键同时按下无法检测出具体按下了哪几个,对于一些按键需求多,而且需要一次开启多个或者需要同时控制的应用场景,矩阵键盘并不太适用。

二、矩阵键盘按键检测原理

检测方法主要有两种,一种是逐行逐列扫描法,另一种是反线法,常用的是逐行逐列扫描法。接下来以4*4矩阵键盘为例,介绍一下这两种方法。在此之前可以先看一下矩阵键盘中按键的连接方法,带着下面这个硬件连接示意图去看软件检测原理。
矩阵键盘硬件连接示意图

1、逐行逐列扫描法

4根行线,4根列线。首先MCU给4个列线的IO输出低电平,4个行线的IO输出高电平。当没有按键按下时,四条行线所连接的IO引脚读取到的将全部是高电平。而当有按键按下时,由于按键按下,导致该按键所在的行列线接通,本身高电平的行线电平被拉低。此时读取所有行线的IO电平可以得知有按键按下。

判断有按键按下后行线IO依旧保持高电平,逐列将列线IO电平置低,读取行线IO电平,如果在一条列线为低电平的时候检测到某一条行线为高电平。此时可以根据行线列线8个IO的电平状态得到一个特定的16进制数,根据这个16进制数可以确定具体是哪个按键按下。

2、反线法

反线法也较为简单,判断是否有按键按下的方法与逐行伫列扫描法相同,首先MCU给4个列线的IO输出低电平,4个行线的IO输出高电平。当没有按键按下时,四条行线所连接的IO引脚读取到的将全部是高电平。而当有按键按下时,由于按键按下,导致该按键所在的行列线接通,本身高电平的行线电平被拉低。此时读取所有行线的IO电平,可以得知有按键按下,同时也能知道被按下的按键位于哪一行。

不同的是后续反线法会将行线IO电平拉低,列线电平IO拉高,这也是这种方法叫做反线法的原因。同样的方法会检测到列线有一条与行线接通,导致电平被拉低。这样又能得出被按下的按键所在的列。如此一来行列确定后就能够确定被按下按键的具体位置。

个人还是更加倾向于逐行逐列扫描法的。

三、矩阵键盘按键检测程序实现

矩阵键盘的检测整理来讲还是比较简单的,这里以STM32F103系列单片机为例,附上一个4*4矩阵键盘检测的程序。

#include "keyboad.h"
#include "delay.h"

void keyboad_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;  //选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	 //设置推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;	  //设置传输速率
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   /* 初始化GPIO */
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;  //选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;	//设置下拉输入模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;	  //设置传输速率
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   /* 初始化GPIO */
	
	GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}
	
u8 Read_KeyValue()
{
	u8 KeyValue=0;
	
	if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f)
	{
		delay_ms(10);
		if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f)
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_0);
			GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
			switch(GPIO_ReadInputData(GPIOA)&0xff)
			{
				case 0x11: KeyValue=1;break;
				case 0x21: KeyValue=5;break;
				case 0x41: KeyValue=9;break;
				case 0x81: KeyValue=13;break;
			}
			
			GPIO_SetBits(GPIOA,GPIO_Pin_1);
			GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3);
			switch(GPIO_ReadInputData(GPIOA)&0xff)
			{
				case 0x12: KeyValue=2;break;
				case 0x22: KeyValue=6;break;
				case 0x42: KeyValue=10;break;
				case 0x82: KeyValue=14;break;
			}
			
			GPIO_SetBits(GPIOA,GPIO_Pin_2);
			GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3);
			switch(GPIO_ReadInputData(GPIOA)&0xff)
			{
				case 0x14: KeyValue=3;break;
				case 0x24: KeyValue=7;break;
				case 0x44: KeyValue=11;break;
				case 0x84: KeyValue=15;break;
			}
			
			GPIO_SetBits(GPIOA,GPIO_Pin_3);
			GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
			switch(GPIO_ReadInputData(GPIOA)&0xff)
			{
				case 0x18: KeyValue=4;break;
				case 0x28: KeyValue=8;break;
				case 0x48: KeyValue=12;break;
				case 0x88: KeyValue=16;break;
			}
			
			GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
			GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
			
			while((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f);
			return KeyValue;
		}
	}
	return 0;
}

版权声明:本文为博主作者:二土电子原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_45217381/article/details/129026341

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年1月16日
下一篇 2024年1月16日

相关推荐

此站出售,如需请站内私信或者邮箱!