矩阵键盘
介绍
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
扫描:
数码管扫描(输出扫描)原理: 显示第1位一显示第2位一显示第3位然后快速循环这个过程,最终实现所有数码管同时显示的效果
矩阵键盘扫描(输入扫描
原理: 读取第1行(列)一读取第2行(列)一读取第3行(列)然后快速循环这个过程,最终实现所有按键同时检测的效果
以上两种扫描方式的共性: 节省I/0口
具体扫描方式
矩阵的扫描可以按行也可按列,但由于内部电路的影响,若按行扫描会导致蜂鸣器的“躁动”,故我们选择按列扫描,先看代码
#include <REGX52.H>
#include "Delay.h"
unsigned char MetrixKey()
{
unsigned char num=0;
P1=0xFF;
P1_3=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=1;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=5;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=9;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=13;}
P1=0xFF;
P1_2=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=2;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=6;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=10;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=14;}
P1=0xFF;
P1_1=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=3;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=7;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=11;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=15;}
P1=0xFF;
P1_0=0;
if(P1_7==0){Delay(20);while(P1_7==0)Delay(10);num=4;}
if(P1_6==0){Delay(20);while(P1_6==0)Delay(10);num=8;}
if(P1_5==0){Delay(20);while(P1_5==0)Delay(10);num=12;}
if(P1_4==0){Delay(20);while(P1_4==0)Delay(10);num=16;}
return num;
}
#include "Delay.h"是作者利用模块化编程加入此处的Delay延时函数
可见,逐列扫描时先分别将每一列对应的I/O口赋为0,其他为1,而后判断该列上四个按键的另一侧的四个I/O口是否为0,若为0则代表此按键被按下,上述代码中也包含了按键消抖,故按下时程序被卡死,松手后反应
(介于I/O口为弱上拉模式,单片机检测低电平,故当某按键两端均为0时,算按下)
若在LCD1692上进行调试,借助上述代码以及LCD1602中的函数,便可显示出所按下按键的键码
由于矩阵键盘的功能就是键入识别,每个按键的意义均可被重复定义,这都取决于代码的内容,故知道了如何扫描矩阵键盘,用它去实现何种功能便都是后话了,故继续做 江协科技 此节视频的笔记
Keil 5的部分使用介绍
Project:工程栏,我们最常用的一栏,在此我们可以添加新文件夹和各种类型的新文件
Books:书籍栏,其中已包含了软件制作商给的用户工具指南和Device Date Books(均全英)可以获取相关知识
Functions:函数栏,若为空白的话说明你的工程里没有函数或者它还没有对你的工程进行扫描,若为后者,则右键单击此栏空白处,点scan Project File 或者下面的current editor file 来控制扫描范围,便可获得对应范围内你所定义的函数了,在此栏中双击函数名便可跳转到你定义它的位置,以进行检验或修改等操作
Templates:模板栏,如其名,可以在此栏中添加和迁移使用模板,比如定义函数时的模板、头文件中使用的固定语句模板、函数注释的常用格式模板等等,使模块的迁移应用更加便捷
六位密码锁
由于我们使用的LCD1602调试工具中的LCD_ShowNum函数所能显示的最大值为65535,故若直接用该函数显示所输入密码,密码最多只能为四位数或有限的有限的五位数
此处选择用数组来暂存密码的每一位并结合for循环来进行显示
每次只显示一位,注意数组单元和显示位置的相对关系
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MetrixKey.h"
void main()
{
LCD_Init();
while(1)
{
unsigned char Keynum = 0;
unsigned int pass = 123456;
char a=0,b=0;
unsigned char TOF=2;
unsigned char h[6];
unsigned char H[6];
for(b=0;b<6;b++)
{
H[b]=pass%10;
pass /=10;
}
Keynum=MetrixKey();
LCD_ShowString(1,1,"Password:");
if(Keynum)
{
if(Keynum<=10)
{
Keynum %=10;
h[a]=Keynum;
a++;
if(a==6)
a=0;
}
if(Keynum==11)
{
for(b=0;b<6;b++)
{
if(h[b]==H[5-b])
TOF=1;
else
TOF=0;
}
}
if(Keynum==12)
{
for(b=0;b<6;b++)
h[b]=0;
}
for(b=0;b<6;b++)
{
LCD_ShowNum(2,6-b,h[b]);
}
if(TOF==1)
LCD_ShowString(2,1,"Congratulations!");
else
LCD_ShowString(2,1,"Sorry");
}
}
}