一、开发板原理图
我们可以看到这个键盘是4*4的,行可以由4个数据接口接收(P1_4~7),列可以由4个数据接口接收(P1_0~3)。
所以我们可让行作为扫描方向,或者列作为扫描方向,进行按键扫描。如何扫描?让4个端口输入,4个端口接收,如果接收到了输入的数据则代表按键按下,电路连通。
比如,我们初始化P2=0xFF,即所有的P2_x都是高电平。然后让P1_0 = 0,去检测P1_4~7哪一个是低电平,这样就完成了最后一列的扫描。
所以,这个很简单的只需要对,端口直接操作即可。
二、矩阵按键按下返回数字
这里需要我们用LCD1602进行显示,看到我们的数据。(或者你也可以用串口输出,都是ok的,只是一种验证的方法)。LCD1602是一个显示器,可以直接找到它的.c.h 文件,直接使用就可。
我们先看列扫描的代码
#include <REGX52.H>
#include "Delay.h"/*** @brief 矩阵键盘读取按键键码* @param 无* @retval KeyNumber 按下按键的键码值如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0*/
unsigned char MatrixKey()
{unsigned char KeyNumber=0;P1=0xFF;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_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_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_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;
}
和我们刚才的思路一样,列置0,然后扫描行的数据。不难看出这里还是贴心的准备消抖的操作,因为还是按键,所以我们还是需要进行消抖。Delay直接生成就好了。
我们回到main函数:
#include <REGX52.H>
#include "Delay.h" //包含Delay头文件
#include "LCD1602.h" //包含LCD1602头文件
#include "MatrixKey.h" //包含矩阵键盘头文件unsigned char KeyNum;void main()
{LCD_Init(); //LCD初始化LCD_ShowString(1,1,"MatrixKey:"); //LCD显示字符串while(1){KeyNum=MatrixKey(); //获取矩阵键盘键码if(KeyNum) //如果有按键按下{LCD_ShowNum(2,1,KeyNum,2); //LCD显示键码}}
}
LCD1602_ShowString 和 LCD1602_ShowNum,根据字面意思就是显示字符串和数字,前两个数字分别是在第几行,第几列显示,第三个参数是显示的字符串和数字,数字的第四个参数是以几位的格式显示比如3位,002.
我们回到代码,这里先进行了初始化,然后进入循环执行部分。我们每一次循环都获取一下哪一个按键按下,存入KeyNum中,然后在LCD中显示。
消抖的部分在矩阵按键部分已经实现了,所以这里不必再进行消抖操作。
三、用矩阵键盘实现---密码锁
恭喜又一次进阶了,我们已经实现了矩阵键盘的读取功能,所以剩下的我们只需要在main中添加逻辑即可。
#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) //如果S1~S10按键按下,输入密码{if(Count<4) //如果输入次数小于4{Password*=10; //密码左移一位Password+=KeyNum%10; //获取一位密码Count++; //计次加一}LCD_ShowNum(2,1,Password,4); //更新显示}if(KeyNum==11) //如果S11按键按下,确认{if(Password==2345) //如果密码等于正确密码{LCD_ShowString(1,14,"OK "); //显示OKPassword=0; //密码清零Count=0; //计次清零LCD_ShowNum(2,1,Password,4); //更新显示}else //否则{LCD_ShowString(1,14,"ERR"); //显示ERRPassword=0; //密码清零Count=0; //计次清零LCD_ShowNum(2,1,Password,4); //更新显示}}if(KeyNum==12) //如果S12按键按下,取消{Password=0; //密码清零Count=0; //计次清零LCD_ShowNum(2,1,Password,4); //更新显示}}}
}
先初始化我们的显示屏,在第一行显示一个文字。随后进入循环,我们和刚才一样需要以数字用于存放我们的按键值,如果按下了,进行数字和功能的判别。若数字小于等于10则为数据输入,如果为11,则为确定,如果为12则代表清除刚才的输入。同时在按下确认键后,和密码进行对比,如果正确在屏幕右上角显示“ok”,若错误显示“ERR”。