速通51单片机————矩阵键盘及其应用

矩阵键盘电路

首先看看矩阵键盘的电路连接:

如果每个按键都要单独进行检查,那么就需要16个接口,但为了节省接口矩阵键盘是采用逐行或者逐列进行扫描,选中一行或者选中一列,然后判断该行(列)中具体哪个按键被按下然后就可以捕捉了,然后通过循环快速扫描四行(列),从而实现对所有按键进行扫描。

独立按键的准双向口

在51单片机中,I/O的工作模式是准双向口。可以双向输入给I/O

当接口输出1时,内部此时是弱上拉电阻(待会会说到)。

当接口输入0时,内部此时是接地状态。

只有接口输出为1时,才能读取状态变化。

弱上拉电阻

弱上拉电阻,通俗易懂的就是,当接口同时输入1和0时,此时接口会选择输出0,若接口输出为0时,需要很大的电流才能使接口输出1

所以为什么在单片机的矩阵键盘中,一般接口处于输出1的状态,这样一旦捕捉到0的变化,就会立刻输出0。

LED显示矩阵键盘按下的数字

这里将复用之前的原代码,即Delay,LCD1602等函数,请自行查看之前的内容。

才之前的基础上,新增matrixKey的头文件与C文件:

matrixKey.h

cpp 复制代码
#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

matrixKey.c

这里是实现读取键盘的实现:

根据前面所说的,我们需要将P1全部接口置1,此时全部不工作

扫描第一列,将P1_3置0,此时第一列工作

然后开始检测第一列的四个按钮(前后需要delay来消抖)

一旦检测到就将记录下该按钮代表的数字,然后return返回。

就这样依次检测1,2,3,4列。

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"

unsigned char MatrixKey()
{
	unsigned char KeyNumber = 0;
	
	P1 = 0xFF;//P1全部置高电平
	P1_3 = 0;//扫描第一列
	if(P1_7 == 0)
	{
		Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 1;
	}
	if(P1_6 == 0)
	{
		Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 5;
	}
	if(P1_5 == 0)
	{
		Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 9;
	}
	if(P1_4 == 0)
	{
		Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 13;
	}

	P1 = 0xFF;//P1全部置高电平
	P1_2 = 0;//扫描第二列
	if(P1_7 == 0)
	{
		Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 2;
	}
	if(P1_6 == 0)
	{
		Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 6;
	}
	if(P1_5 == 0)
	{
		Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 10;
	}
	if(P1_4 == 0)
	{
		Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 14;
	}

	P1 = 0xFF;//P1全部置高电平
	P1_1 = 0;//扫描第三列
	if(P1_7 == 0)
	{
		Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 3;
	}
	if(P1_6 == 0)
	{
		Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 7;
	}
	if(P1_5 == 0)
	{
		Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 11;
	}
	if(P1_4 == 0)
	{
		Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 15;
	}

	P1 = 0xFF;//P1全部置高电平
	P1_0 = 0;//扫描第四列
	if(P1_7 == 0)
	{
		Delay(20);while(P1_7 == 0);Delay(20);KeyNumber = 4;
	}
	if(P1_6 == 0)
	{
		Delay(20);while(P1_6 == 0);Delay(20);KeyNumber = 8;
	}
	if(P1_5 == 0)
	{
		Delay(20);while(P1_5 == 0);Delay(20);KeyNumber = 12;
	}
	if(P1_4 == 0)
	{
		Delay(20);while(P1_4 == 0);Delay(20);KeyNumber = 16;
	}
	
	return KeyNumber;
	
}

main.c

现在来到主函数:

首先将LCD初始化,第一列显示如下代码的字符串。

然后开始循环接收MatrixKey函数所返回的字符。

由于返回的字符初始值为0,所以我们可以直接利用该字符进行判断条件。

所以一旦接收到字符,此时就调用LCDshow函数显示该字符即可。

cs 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "matrixKey.h"

unsigned char KeyNum;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"MatrixKey");
	while(1)
	{
		KeyNum = MatrixKey();
		if(KeyNum)
		{
			LCD_ShowNum(2,1,KeyNum,2);
		}
	}
}

矩阵键盘密码锁

在刚刚的基础上进行操作,制作一个四位密码的锁

处理按下的数字转化成密码

当按下之后,我们需要对该数字进行处理:

我们输入的数字必须是0-9,但是键盘并没有0这个按键

所以我们将按键10当成0

每按下一个按键,都让Password自身乘10再加上按下的字数,这样就完成一次密码输入。

由于是四位密码,我们需要一个计数变量,密码小于4时则可以进行密码输入。

每输入一次那么就刷新显示一次。

cpp 复制代码
			if(KeyNum <= 10)
			{
				if(count < 4)
				{
					Password *= 10;
					Password += KeyNum%10;
					count++;
				}
				LCD_ShowNum(2,1,Password,4);
			}

确认密码

我们将按键11设为确认键。

一旦按下按键11,则开始进行判断

如果输入密码为指定密码。则在第一行最右边显示OK,否则显示ERR,此时刷新密码和计数,并刷新显示。

如果输入密码不正确,那么显示ERR,同样刷新密码和计数,以及刷新显示。

cpp 复制代码
			if(KeyNum == 11)
			{
				if(Password == 2345)
				{
					LCD_ShowString(1,14,"OK ");
					Password = 0;
					count = 0;
					LCD_ShowNum(2,1,Password,4);
				}
				else
				{
					LCD_ShowString(1,14,"ERR");
					Password = 0;
					count = 0;
					LCD_ShowNum(2,1,Password,4);
				}
			}

取消输入

我们将按键12设为取消输入。

一旦按下按键12,此时清空计数与密码,并刷新显示。

cpp 复制代码
			if(KeyNum == 12)
			{
				count = 0;
				Password = 0;
				LCD_ShowNum(2,1,Password,4);
			}

密码锁的完整代码

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "matrixKey.h"

unsigned char KeyNum;
unsigned int Password, count;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"Password!");
	while(1)
	{
		KeyNum = MatrixKey();
		if(KeyNum)
		{
			if(KeyNum <= 10)
			{
				if(count < 4)
				{
					Password *= 10;
					Password += KeyNum%10;
					count++;
				}
				LCD_ShowNum(2,1,Password,4);
			}
			if(KeyNum == 11)
			{
				if(Password == 2345)
				{
					LCD_ShowString(1,14,"OK ");
					Password = 0;
					count = 0;
					LCD_ShowNum(2,1,Password,4);
				}
				else
				{
					LCD_ShowString(1,14,"ERR");
					Password = 0;
					count = 0;
					LCD_ShowNum(2,1,Password,4);
				}
			}
			if(KeyNum == 12)
			{
				count = 0;
				Password = 0;
				LCD_ShowNum(2,1,Password,4);
			}
		}
	}
}
相关推荐
d111111111d2 小时前
STM32 I2C通信详解:从机地址与寄存器地址的作用
笔记·stm32·单片机·嵌入式硬件·学习
普中科技2 小时前
【普中51单片机开发攻略--基于普中-2&普中-3&普中-4】-- 第 14 章 矩阵按键实验
单片机·嵌入式硬件·51单片机·开发板·按键检测·矩阵按键·普中科技
搞机械的假程序猿2 小时前
普中51单片机学习笔记-LCD1602液晶显示
笔记·学习·51单片机
Mapple.3 小时前
TMS320C6748的初始化与STM32做个类比
stm32·单片机·嵌入式硬件
俊俊谢3 小时前
华大HC32F460轮询方式SPI通讯配置
单片机·嵌入式硬件·spi·hc32f460
TESmart碲视3 小时前
如何设置双屏KVM切换器(Win+Mac双屏双系统共享一套键鼠):手把手详细指南
macos·计算机外设·mst·kvm切换器·tesmart·双屏kvm切换器·tesmart碲视
听情歌落俗3 小时前
MPU6050
单片机·嵌入式硬件
d111111111d3 小时前
STM32定时器中断配置详解:以TIM2为例
笔记·stm32·单片机·嵌入式硬件·学习
Q_21932764553 小时前
基于51单片机的智能家居防火防盗报警系统设计
嵌入式硬件·51单片机·智能家居