一、 设计要求 设计一个由单片机控制的电子密码锁,要求如下:
- 能设定一组4位的数字开启密码(设定密码功能)
- 用LED小灯代替锁开启显示,输入密码正确,则小灯亮起(开锁功能)
- 如果3次密码错误,则进行鸣叫报警,并在1分钟之内不能再次输入(报警功能)
- 密码输入显示在数码管上,输入正确显示on,输入错误显示err(显示功能)
- 可在以上功能上扩展。
二、原理说明 该程序用C51语言,Keil5软件及proteus进行仿真。 用到的硬件设备有AT89C52,蜂鸣器,LCD1602,上拉电阻,三极管,按钮 代码部分对不同的方法进行封装,主要是延时函数Delay(),蜂鸣器发声函数Beep(),矩阵键盘函数,LCD1602显示函数以及主要功能实现main函数。
1、 矩阵键盘输入 根据矩阵键盘的电平翻转对16个按键进行数字的定义,并返回每个按键对应的数字。Main函数里对返回的数字进行判断来确定按下的是哪一个按键,并对相关功能进行定义。在这里我定义0~9数字为输入的正常数字,按键11定义为确定按键,即当矩阵键盘函数MatrixKey()函数返回值为11时定义确认键功能,矩阵键盘函数MatrixKey()函数返回值为12时定义撤销键功能,矩阵键盘函数MatrixKey()函数返回值为13时定义重置密码功能。注意按键消抖。 代码如下:
#include <REGX52.H>
#include "Delay.h"
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;
}
2、 LCD1602进行显示 主要使用的方法为以下几种方法 注意LCD1602的显示范围,行是12,列数是116
3、 延时函数 延时函数非常简单,就是一个简单的循环 代码如下:
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
4、 蜂鸣器 蜂鸣器的声音的频率取决于延时情况,注意调到合适频率 代码如下:
#include <REGX52.H>
#include "Delay.h"
sbit beep = P2^2;
void Beep()
{
beep = ~beep;
Delay(500);
}
5、 main函数 main函数是对整个电子密码锁主要逻辑的实现 首先定义一个password接收输入的密码,count接收输入次数,scount定义错误次数,rightpass接收正确密码。对键盘输入的数字用KeyNum进行接收。0~9数字为输入的正常数字,按键11定义为确定按键,即当矩阵键盘函数MatrixKey()函数返回值为11时定义确认键功能,矩阵键盘函数MatrixKey()函数返回值为12时定义撤销键功能,矩阵键盘函数MatrixKey()函数返回值为13时定义重置密码功能。 三、电路设计 电路主要包括四块,单片机AT89C52,矩阵键盘,蜂鸣器,LCD1602
AT89C52的P0口和P2口的P25,P26,P2^7控制LCD1602,P0口需接上拉电阻 AT89C52的P1口控制矩阵键盘。这里矩阵键盘按列扫描,首先对P1进行初始化P1 = 0xFF,然后循环依次从第一列到第四列的接口赋值0(P10,P11,P12,P13),然后对行的接口进行扫描检测。如果某一个按键按下,此时该按键列的接口为0,那么该按键行的接口也为0。根据行与列判断是哪一个按键进行相应赋值定义。 AT89C52的P3^0控制LED小灯。 AT89C52的P22控制蜂鸣器。蜂鸣器分为有源蜂鸣器和无源蜂鸣器(振荡源),我选择的为有源蜂鸣器,将蜂鸣器的电压调为2v。我用的NPN三极管,P22=1时三极管导通,蜂鸣器发声。
四、仿真结果 点击开始,LCD1602显示PASSWORD,提示输入密码。
输入一个四位密码
点击RIGHT进行确认,判断是否是正确密码
密码不正确,显示ERR,密码输入清零 重新输入,错误三次后蜂鸣器会报警,此时无法输入
输入初始正确密码2001,显示ON,小灯两起
输入一个密码1256,按下EXCHANGE键,对正确密码进行修改
此时重新输入之前的初始正确密码2001,已经错误
输入1256
输入一个密码错误时,按CANCEL键可清零
五、结果分析 功能需求均能满足。LCD1602可正常显示,密码输入正常,错误次数超过3次蜂鸣器报警并1min内无法输入,密码输入正确会显示ON。输入数字错误可取消重新输入。可软件对正确密码进行修改。正确密码初始为2001,进行密码修改后在不掉电情况下正确密码可变,但掉电丢失,正确密码恢复为初始2001.尝试用硬件24C02进行记忆,可成功写入和读出,但写入的数字存在错误。无法完全实现,以后会尝试从这方面进行改进,并优化代码逻辑结构。
部分代码参考于https://www.bilibili.com/video/BV1Mb411e7re?share_source=copy_web
|