嵌入式开发

您所在的位置:网站首页 逐行扫描法代码 嵌入式开发

嵌入式开发

2024-07-11 23:37| 来源: 网络整理| 查看: 265

文章目录 一、前言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; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3