本密码锁是利用8051单片机的控制结合1602lcd,设计的一个微电脑lcd密码锁,可以用在需要密码输入的场合中,例如要当门禁用时,需要实际配合电子门锁。也可以设计在保险中做密码锁控制中。本密码锁应用的知识主要有:
1. 8051 4x4矩阵键盘扫描输入
2. 1602 lcd显示
3. 密码比较处理的设计方法
4. 定时器的使用
5. 24cxxx的应用等
功能说明:
1. 使用lcd显示器来显示密码输入的相关消息及提示
2. 可以设置6位数字(0-9)密码
3. 内定另一组数字密码为:000000
4. 密码输入正确则继电器启动2s
5. 密码输入正确或错误都有相应的声音提示
6. 密码输入3次错误,系统将自动锁定,30分钟内不准使用,30分钟后自动开启
7. 密码输入时,如果在10秒内没有按键,表示放弃本次输入,则自动跳出密码输入状态,进入欢迎界面
8. 可以修改密码或用原始密码
9. 断电后密码仍然存在(保存在24c02中)
10.具有按键复位功能
硬件连接:
/*1602 lcd连接线图:
---------------------------------------------------
| lcm-----51 | lcm-----51|lcm------51 |
| ----------------------------------------------- |
| db0-----p0.0 | db4-----p0.4 | rs-------p2.0 |
| db1-----p0.1 | db5-----p0.5 | rw-------p2.1 |
| db2-----p0.2 | db6-----p0.6 | e--------p2.2 |
| db3-----p0.3 | db7-----p0.7 | vlcd接1k电阻到gnd |
---------------------------------------------------
接口说明:1. p1口: 4x4矩阵键盘
2. p2.4 工作指示灯
3. p2.5 继电器控制端
4. p3.7 蜂鸣器控制端
5. p3.3 24c02时钟端
6. p3.4 24c02数据端
/*接盘按键说明:
--------------------------------------------------
| 1 | 2 | 3 | a |
- - - - - - - - - - - - -
| 4 | 5 | 6 | b |
- - - - - - - - - - - - -
| 7 | 8 | 9 | c |
- - - - - - - - - - - - -
| * | 0 | # | d |
--------------------------------------------------
注:a--表示输入密码
b--表示设置新密码
c--复位端口
附加说明:
1. lcd1602驱动-----------明皓
2. 4x4键盘扫描-----------kt学习综合实验源程序
3. 密码比较原理----------8051单片机课程设计实训教材
4. 24c02的读写操作-------伟纳电子me300b单片机开发系统演示程序
zhaojun 2007/10/1
部分代码:
//========================================== 主函数部分 ==================================================
/*****************************************************
函 数 名:void clearmen(void)
功 能:系统初始化
说 明:对系统用的标志位和定时器进行初始化
入口参数:无
返 回 值:无
*****************************************************/
void clearmen(void)
{
flag1= 1; // choice_menu()调用标志
signx= 1; // 循环标志
flag = 1; // 调用输入新密码提示标志位
mark = 1; // 循环标志位
num = 0; // 按键错误计数器
th0=0x3c;tl0=0xb0; // 50ms定时初值
th1=0x3c;tl1=0xb0; // 50ms定时初值
tmod=0x11;et0=1;tr0=0;et1=1;tr1=0;ea=1;
}
/*****************************************************
函 数 名:main()
功 能:主函数
说 明:对按键和显示进行控制
入口参数:无
返 回 值:无
*****************************************************/
void main(void)
{
uchar key_value;
delay400ms(); // 启动等待,等lcm讲入工作状态
lcminit(); // lcm初始化
delay400ms();
clearmen(); // 系统初始化
while(1)
{
p1=0xf0;
if(((p1&0xf0)!=0xf0)&(flag1==1)&(num<3)) // 有键按下
{
key_value=key_switch(); // 按键扫描
if(key_value!=0) // 的确有键按下
{
choice_menu(); // 调用选择程序
flag1=0; // choice_menu()调用标志
signx=1; // 循环标志
}
while(signx==1)
{
tr0=0; // 定时器0关,从先开始计时
tr0=1; // 定时器0开
p1=0xf0; // p1口赋值,从而判断有无按键
if((p1&0xf0)!=0xf0)
{
key_value=key_switch(); // 按键扫描
if(key_value==65) // 如果按键是"a",则输入密码
{
while(mark==1)
{
password_importation(); // 密码输入
}
flag1=1; // choice_menu()调用标志
signx=0; // 循环标志
}
if(key_value==66) // 如果按键是"b",则输入新密码
{
while(mark==1) // 输入前比较秘密,密码正确进入新密码设置
{ // 密码错误退出密码设置
password_importation(); // 密码输入
}
//-------------------------------
if(mark0!=0) // mark0=1:密码比较正确可以输入新密码
{ // mark0=0:密码比较错误不能输入新密码
mark=1; // 进入循环标志
while(mark==1)
{
newpassword_set(); // 新密码设置函数
}
mark=1; // 进入循环标志
while(mark==1)
{
newpassword_set_again(); // 再次输入密码
}
}
flag1=1; // choice_menu()调用标志
signx=0; // 循环标志
}
}
}
}
else
{
welcome_face(); // 欢迎界面
mark = 1; // 循环标志
mark0= 0; // 是否输入新密码标志位
flag1=1; // choice_menu()调用标志
writecommandlcm(0x0c,1); // 关光标显示
sign=(bit)readcurrent(10); // 密码比较标志位
}
if(num==3) // 3次输入错误密码,系统锁定30min
{
et1=1;tr1=1; // 开定时器t1,定时30分钟
}
}
}
//========================================== 密码控制部分 ==================================================
/*****************************************************
函 数 名:void newpassword_set_again(void)
功 能:第二次输入密码
说 明:第二次输入密码并存入暂存器,再调用比较程序
入口参数:无
返 回 值:无
*****************************************************/
void newpassword_set_again(void)
{
bit sign1;
uchar key_data;
p1=0xf0; // 判断是否有键按下
if(flag==1)
{
newpassword_again(); // 显示密码输入界面
delay400ms();
flag=0; // 调用输入新密码提示标志位
count=0; // 按键次数计数器置0
delay400ms();
}
if((p1&0xf0)!=0xf0) // 判断是否有键按下
{
key_data=key_switch(); // 调用按键转换程序
if((key_data!=0)&(key_data!=65)&(key_data!=66)&(key_data!=67)&(key_data!=68)&(key_data!=35)&(key_data!=42))
{//按键不能为数字(0~9)以外.a b c d # *
count ; // 按键次数器加1
led_hint(); // 按键指示
beep(); // 按一下键发一音
sign1=1; // 有键按下标志位
}
}
if((sign1==1)&(flag==0)) // 有键按下
{
scan_starnumber(); // 在密码显示区显示" ****** "
sign1=0; // 按键标志位清0
t_password[count-1]=key_data; // 按键值放入密码暂存器
}
if(count==6) // 6次按键则进行密码比较
{
count=0; // 计算清0,从先计数
flag =1; // 调用输入新密码提示标志位
mark =0; // 循环标志位
writecommandlcm(0x0c,1); // 关光标显示
newpassword_comparison(); // 新密码设置比较
}
}
/*****************************************************
函 数 名:void newpassword_comparison(void)
功 能:第二次输入密码比较
说 明:对第一次输入的密码与第二次输入的密码进行比较
入口参数:无
返 回 值:无
*****************************************************/
void newpassword_comparison(void)
{
uchar number=0;
while((t_password[number]==n_password[number])&(number<6))// 密码比较
{
number ; // 计数值加1
}
if(number>=6) // 密码正确
{
newpassword_ok(); // 新密码设置成功提示
writetorom(t_password,0,6); // 密码设置成功,则把密码存入24c02中
sign =1; // 比较新密码标志
writecurrent((uchar)sign,10); // 存入标志位
delay400ms();
beep(); // 正确提示音
delay400ms();
beep();
mark=0;
}
else // 密码错误,报警
{
newpassword_error(); // 新密码设置失败提示
num=0;
sign =0; // 比较旧密码标志
delay400ms();
beep();beep();beep(); // 错误提示音
delay400ms();
beep();beep();beep();
delay1s(); // 延时1s
mark=0;
}
}
/*****************************************************
函 数 名:void newpassword_set(void)
功 能:新密码设置
说 明:修改密码
入口参数:无
返 回 值:无
*****************************************************/
void newpassword_set(void)
{
bit sign1;
uchar key_data;
p1=0xf0; // 判断是否有键按下
if(flag==1)
{
newpassword_face(); // 显示密码输入界面
delay400ms();
flag=0; // 调用输入新密码提示标志位
count=0; // 按键次数计数器置0
delay400ms();
}
if((p1&0xf0)!=0xf0) // 判断是否有键按下
{
key_data=key_switch(); // 调用按键转换程序
if((key_data!=0)&(key_data!=65)&(key_data!=66)&(key_data!=67)&(key_data!=68)&(key_data!=35)&(key_data!=42))
{//按键不能为数字(0~9)以外.a b c d # *
count ; // 按键次数器加1
led_hint(); // 按键指示
beep(); // 按一下键发一音
sign1=1; // 有键按下标志位
}
}
if((sign1==1)&(flag==0)) // 有键按下
{
scan_starnumber(); // 在密码显示区显示" ****** "
sign1=0; // 按键标志位清0
n_password[count-1]=key_data; // 按键值放入密码暂存器
}
if(count==6) // 6次按键则进行密码比较
{
count=0; // 计算清0,从先计数
flag =1; // 调用输入新密码提示标志位
mark =0; // 循环标志位
writecommandlcm(0x0c,1); // 关光标显示
}
}
/*****************************************************
函 数 名:void password_importation(void)
功 能:密码输入
说 明:输入密码并调用密码比较函数进行比较
入口参数:无
返 回 值:无
*****************************************************/
void password_importation(void)
{
bit sign1;
uchar key_data;
p1=0xf0; // 判断是否有键按下
if(((p1&0xf0)!=0xf0)&(flag==1)) // 有键按下,且是第一次
{
key_data=key_switch();
if(key_data!=0)
{
pass_face(); // 显示密码输入界面
delay400ms();
flag=0; // 调用密码输入提示标志位
count=0; // 输入密码个数计数器置0
delay400ms();
}
}
if((p1&0xf0)!=0xf0) // 判断是否有键按下
{
key_data=key_switch(); // 调用按键转换程序
if((key_data!=0)&(key_data!=65)&(key_data!=66)&(key_data!=67)&(key_data!=68)&(key_data!=35)&(key_data!=42))
{//按键不能为数字(0~9)以外.a b c d # *
count ; // 按键次数器加1
led_hint(); // 按键指示
beep(); // 按一下键发一音
sign1=1; // 有键按下标志位
}
}
if((sign1==1)&(flag==0)) // 有键按下
{
scan_starnumber(); // 在密码显示区显示" ****** "
sign1=0; // 按键标准位清0
t_password[count-1]=key_data; // 按键值放入密码暂存器
}
if(count==6) // 6次按键则进行密码比较
{
count=0; // 计算清0,从先计数
flag =1; // 调用密码输入提示标志位
mark =0; // 循环标志位
writecommandlcm(0x0c,1); // 关光标显示
if(sign==0)
passwordcomparison(0); // 输入按键与原始密码比较
else passwordcomparison(1); // 输入按键与新密码比较
}
}
/*****************************************************
函 数 名:void scan_starnumber(void)
功 能:显示密码位为星号
说 明:在密码显示区显示 " ****** "
入口参数:无
返 回 值:无
*****************************************************/
void scan_starnumber(void)
{
switch(count) // 在相应的地方显示"*"
{
case 1:displayonechar(5,1,42);break; //-----*-----------//
case 2:displayonechar(6,1,42);break; //------*----------//
case 3:displayonechar(7,1,42);break; //-------*---------//
case 4:displayonechar(8,1,42);break; //--------*--------//
case 5:displayonechar(9,1,42);break; //---------*-------//
case 6:displayonechar(10,1,42);break; //----------*------//
} //-----*******-----//
}
/*****************************************************
函 数 名:void passwordcomparison(bit mark)
功 能:密码比较程序
说 明:对输入密码进行比较
入口参数:mark:当mark=1时,对原始密码进行比较;当mark=0时,对原始密码进行比较
返 回 值:无
*****************************************************/
void passwordcomparison(bit mark1)
{
uchar number=0;
if(mark1==0) // 输入按键与原始密码比较
{
while((t_password[number]==o_password[number])&(number<6)) // 密码比较
{
number ; // 计数值加1
}
}
else // 输入按键与新密码比较
{
readfromrom(n_password,0,6);
while((t_password[number]==n_password[number])&(number<6)) // 密码比较
{
number ; // 计数值加1
}
}
if(number>=6) // 密码正确
{
mark0=1; // 进入新密码设置
password_ok(); // 调用密码输入正确提示函数
rel=0; // 继电器开启,即密码锁开启
delay400ms();
beep();beep(); // 正确提示音
delay400ms();
beep();beep();
delay1s(); // 延时2s
delay1s();
rel=1; // 继电器关闭,即密码锁开启
mark=0; // 退出循环
num=0;
}
else // 密码错误,报警
{
mark0=0; // 新密码输入控制位
password_error(); // 调用密码输入错误提示函数
delay400ms();
beep();beep();beep();beep(); // 错误提示音
delay400ms();
beep();beep();beep();beep();
delay1s(); // 延时1s
mark=0; // 退出循环
num ; // 密码错误输入计数器
}
}




热门文章

