前言
介绍矩阵键盘,并通过LCD1602来检测矩阵键盘的使用
一、矩阵键盘的介绍
原理与数码管差不多,矩阵按键是先确定行,再确定列,而需要实现和独立按键一样的效果就需要按键与按键的赋值操作快速进行(扫描),达到近似于独立按键的效果,和数码管独立显示数据的原理一样,都是通过快速扫描达到效果
看独立按键与矩阵按键的官方模块图
可以看出原理一样,将每四个按键的一端用一个I/O口控制,即四个I/O口控制行,四个I/O口控制列,按键一般都是低电平驱动,给0选中,按下时为0。
二、实现简易密码验证
实现思路
定义unsigned char MatrixKey();用于返回按下按键的序号,通过主函数再循环中对MatrixKey()的不断调用,用于速度极快,所以我们按下的按键都会被扫描到。然后可以使用if或switch语句对每个按键添加功能。
封装按下哪个按键的函数
MatrixKey.c代码如下
#include <REGX52.H>
#include "Delay.h"
// 返回按键
unsigned char MatrixKey(){
unsigned char keyNum = 0;
// 选中第一列
P1 = 0xff;
P1_3 = 0;
if(P1_7 == 0){
// 消抖
Delayms(20);
while(P1_7 == 0);
Delayms(20);
keyNum = 1;
}
if(P1_6 == 0){
Delayms(20);
while(P1_6 == 0);
Delayms(20);
keyNum = 5;
}
if(P1_5 == 0){
Delayms(20);
while(P1_5 == 0);
Delayms(20);
keyNum = 9;
}
if(P1_4 == 0){
Delayms(20);
while(P1_4 == 0);
Delayms(20);
keyNum = 13;
}
// 选中第二列
P1 = 0xff;
P1_2 = 0;
if(P1_7 == 0){
Delayms(20);
while(P1_7 == 0);
Delayms(20);
keyNum = 2;
}
if(P1_6 == 0){
Delayms(20);
while(P1_6 == 0);
Delayms(20);
keyNum = 6;
}
if(P1_5 == 0){
Delayms(20);
while(P1_5 == 0);
Delayms(20);
keyNum = 10;
}
if(P1_4 == 0){
Delayms(20);
while(P1_4 == 0);
Delayms(20);
keyNum = 14;
}
// 选中第三列
P1 = 0xff;
P1_1 = 0;
if(P1_7 == 0){
Delayms(20);
while(P1_7 == 0);
Delayms(20);
keyNum = 3;
}
if(P1_6 == 0){
Delayms(20);
while(P1_6 == 0);
Delayms(20);
keyNum = 7;
}
if(P1_5 == 0){
Delayms(20);
while(P1_5 == 0);
Delayms(20);
keyNum = 11;
}
if(P1_4 == 0){
Delayms(20);
while(P1_4 == 0);
Delayms(20);
keyNum = 15;
}
// 选中第四列
P1 = 0xff;
P1_0 = 0;
if(P1_7 == 0){
Delayms(20);
while(P1_7 == 0);
Delayms(20);
keyNum = 4;
}
if(P1_6 == 0){
Delayms(20);
while(P1_6 == 0);
Delayms(20);
keyNum = 8;
}
if(P1_5 == 0){
Delayms(20);
while(P1_5 == 0);
Delayms(20);
keyNum = 12;
}
if(P1_4 == 0){
Delayms(20);
while(P1_4 == 0);
Delayms(20);
keyNum = 16;
}
return keyNum;
}
调用MatrixKey()并使用LCD1602显示
主函数main.c如下
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char KeyNum; // 接取按键返回值
unsigned int Password; // 接取密码内容
unsigned int count; // 计数,避免密码输入溢出
void main(){
LCD_Init();
LCD_ShowString(1,1,"password:");
while(1){
KeyNum = MatrixKey();
if(KeyNum){
// 即0-9十位可作为密码的数字,第十位为0
// 密码最大4位
if(KeyNum<=10 && count<4){
Password *= 10; // 每运行一次把当前密码左移一位
Password += KeyNum%10; // 把新的数字加于末尾
count++;
LCD_ShowNum(2,1,Password,4);
}
// 确认,验证密码
if(KeyNum == 11){
if(Password == 1234){
LCD_ShowString(1,11,"right!");
// 清空密码与显示
Password = 0;
count = 0;
LCD_ShowNum(2,1,Password,4);
// 延时2s后不显示
Delayms(2000);
LCD_ShowString(1,11," ");
}else{
LCD_ShowString(1,11,"error!");
// 清空密码与显示
Password = 0;
count = 0;
LCD_ShowNum(2,1,Password,4);
// 延时2s后不显示
Delayms(2000);
LCD_ShowString(1,11," ");
}
}
// 取消效果
if(KeyNum == 12){
// 清空密码与显示
Password = 0;
count = 0;
LCD_ShowNum(2,1,Password,4);
LCD_ShowString(1,11," ");
}
}
}
}
注意
- 在设置密码时是看直接使用十进制的进位方式还是使用数组一位一位拼接的方式,采用进位方式时要注意数据结构的范围大小,避免溢出
- 还要注意LCD1602可显示的范围