【51单片机系列】矩阵按键介绍

本节实现的功能是:通过开发板上的矩阵键盘控制静态数码管显示对应的键值0-F。

文章目录

一、矩阵按键介绍

独立键盘与单片机连接时,每一个按键都需要单片机的一个I/O口。若某单片机系统需要较多按键,如果用独立按键便会占用过多的I/O口资源。

当用到多个按键时,为了减少I/O口引脚,引入了矩阵按键。比如4*4矩阵键盘。

对于4*4矩阵键盘,开发板上通常将16个按键排成4行4列。第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线。将这8根线连接到单片机的8个I/O口上,通过程序扫描键盘可以检测16个键。

无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,即检测与该键对应的I/O口是否为低电平。独立键盘有一端固定为低电平而矩阵键盘两端都与单片机I/O口相连,在检测时需编程通过单片机I/O口送出低电平。检测方法最常用的是行列扫描和线翻转法。

  • 行列扫描法检测时,先送一列为低电平,其余几列全为高电平,此时确定列数;然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平,此时确定了行数,便可以确认当前被按下的键是哪一行哪一列的。用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键,当有按键被按下时便可判断出按下的键是哪一个键。
  • 线翻转法检测时,就是使所有行线为低电平时,检测所有列线是否有低电平,如果有,就记录列线值;然后再翻转,使所有列线都为低电平,检测所有行线的值。由于有按键按下,行线的值也会有变化,记录行线的值,从而就可以检测到全部按键。

矩阵按键也需要按键消抖。

二、硬件设计

实现功能:通过开发板上的矩阵键盘控制静态数码管显示对应的键值0-F。用到的硬件资源有:

  • 动态数码管
  • 4*4矩阵按键

硬件电路如下:

从上图可以看出,4*4矩阵按键引出的8根控制管脚直接连接到51单片机的P1口上。

三、软件设计

要想51单片机能够检测按键是否按下,必须通过单片机管脚来控制矩阵按键。

代码实现如下:

c 复制代码
/*
	实现功能:使用独立按键控制指示灯的亮灭
	[2023-12-06] zoya
*/
#include "reg52.h"

typedef unsigned char u8;
typedef unsigned int u16;


#define GPIO_DIG P0  // 动态数码管
#define GPIO_KEY P1  // 矩阵按键

u8 keyVal;  // 记录按键位置
u8 code smg[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};  // 共阴极数码管

// 延时函数,i=1延时10us
void delay(u16 i)
{
	while(i--);
}

// 检测矩阵按键的哪个键按下,线翻转法检测哪个按键被按下
void KeyDown()
{
	char a = 0;
	GPIO_KEY = 0x0f;  // 所有行线全部为低电平
	if(0x0f != GPIO_KEY)  // 检测是否有键被按下,如果有键被按下,GPIO_KEY不会为0x0f
	{
		delay(1000);  // 延时10ms进行消抖
		if(0x0f != GPIO_KEY)  // 再次判断是否有键被按下
		{
			// 测试列
			GPIO_KEY = 0x0f;
			// 检测列是否有低电平
			switch(GPIO_KEY)
			{
				case 0x07: keyVal = 0; break;  // 第一列的某行被按下,假设是第一行
				case 0x0b: keyVal = 1; break;  // 第二列的某行被按下,假设是第一行
				case 0x0d: keyVal = 2; break;  // 第三列的某行被按下,假设是第一行
				case 0x0e: keyVal = 3; break;  // 第四列的某行被按下,假设是第一行
			}
			
			// 测试行
			GPIO_KEY = 0xf0;
			switch(GPIO_KEY)
			{
				case 0x70: keyVal = keyVal + 0; break;  // 第一行的某列被按下
				case 0xb0: keyVal = keyVal + 4; break;  // 第二行的某列被按下
				case 0xd0: keyVal = keyVal + 8; break;  // 第三行的某列被按下
				case 0xe0: keyVal = keyVal + 12; break;  // 第四行的某列被按下
			}
			
		}
		
		while((a <50) && (GPIO_KEY != 0xF0))  // 检测按键松手检测
		{
			delay(100);
			a++;
		}
	}
}


void main()
{
	while(1)
	{
		KeyDown();
		GPIO_DIG = smg[keyVal];
	}
}

仿真结果:

相关推荐
ZJU_统一阿萨姆1 小时前
【算子开发】矩阵乘法(GEMM)入门与共享内存优化
人工智能·线性代数·矩阵·系统架构
恒锐丰小瑞5 小时前
率能SS8841T 40V/2.5A/双通道H桥驱动芯片,PWM控制接口与低导通电阻(350mΩ),用于POS打印机/安防相机/机器人
单片机·嵌入式硬件·机器人
zcmodeltech6 小时前
钢铁冶金沙盘模型控制系统设计与实现:高炉-连铸-热轧多工序联动方案
分布式·stm32·单片机·嵌入式硬件·交互
徽京人7 小时前
VS Code 接入Esp 32步骤
vscode·单片机·嵌入式硬件
招财小梗7 小时前
AI矩阵获客,品牌连锁落地方案揭秘
大数据·人工智能·矩阵
QH139292318808 小时前
Keysight N5183B N5183B 微波模拟信号发生器
网络·单片机·嵌入式硬件·集成测试·信息与通信
笨笨饿9 小时前
#110_SCH3000 平台图传系统配置指南:从 DVP 摄像头到 UVC/WiFi 双通道传输
c语言·stm32·单片机·嵌入式硬件·物联网·vim
千秋岁rr11 小时前
5.0 TIM
单片机·嵌入式硬件
qq_4017004111 小时前
ADC基准电压与参考电压详细解读:以STM32和28335为例
stm32·单片机·嵌入式硬件
zcmodeltech13 小时前
水利水电沙盘模型控制系统设计与实现:多场景多工况联动方案
网络·stm32·嵌入式硬件·制造·多分类