今天给大家介绍一款业余制作的电子密码锁,有PCB、原理图、仿真图(前期用,后期直接上PCB板)。此程序没有做用外部存储器,所以不支持修改密码,我后续有时间慢慢在改进加上去,然后在添加指纹识别模块,有时间再继续更新。毕竟是业余时间做的,可能在有些方面不是很完善,希望大家都来观摩观摩,出出建议。
一、功能介绍:
1、输入8位密码,即可开锁。
2、输入9次纯数字,显示错误,并红灯提醒。
3、没有输入完8位密码,按下确认键,提醒错误并红灯提醒。
4、密码输入错误三次,锁定键盘并且蜂鸣器提醒5秒左右。
5、输入错误可以退格、清零。
6、1602显示模块会有60秒定时显示,没操作键盘50秒后,清楚数据,并且闪红灯提醒。
7、1602显示模块会有输入位数显示,提醒输入密码。
8、程序有密码数值存储在数组,可用于显示等操作。(制作礼品盒的时候可用)
9、本PCB,设计有外部存储器24C02的硬件位置,方便后期可添加!
二、PCB提醒
1、本次上传的PCB的1602的1.2引脚正负极已经调整过来(实物PCB的1.2脚反了,当时没注意,都烧坏了一块1602··········其他没有问题)。
2、我这里还有一版的PCB,硬件设计的请移步我的另一个贴,上面有更正的硬件说明。http://www.51hei.com/bbs/dpj-183892-1.html
三、最后说几句
1、有电子相关专业(专科)的同学们,可以用这个作为毕业设计,应该问题不大。
2、自己用动手能力的朋友,可以自己改成简易的电子密码箱,用来装礼物,给自己的朋友或者女朋友都可以。个人感觉还挺不错,感兴趣的朋友可以尝试,我有空了你也会做一个这样的。
3、我的一些实物视频可以去我的抖音上看,抖音号:5946BNYZD。
4、哔哩哔哩视频:https://www.bilibili.com/video/BV1QK411W7w9/
制作出来的实物图如下:
实物图二
实物图一
两版电路板
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code szjianzhibiao[]={0x77,0x7b,0x7d,
- 0xb7,0xbb,0xbd, //矩阵数字键盘键值
- 0xd7,0xdb,0xdd,
- 0xeb};
- uchar code gnjianzhibiao[]={0x7e,0xbe,0xde, //矩阵功能键盘键值
- 0xee,0xed,0xe7};
-
- uchar code mima[]={0x77,0x7d,0x77,0xb7, //设定的密码
- 0x77,0x7d,0x77,0xb7};
- uchar code table[]="HOLLE! User";
- uchar code table1[]="Password";
- uchar code table2[]="********";
- uchar code table3[]=" error!";
- uchar code table4[]=" OK! ";
- uchar code table5[]=" "; //抹除输入痕迹的空字符串
- uchar code table6[]="0123456789";
- uchar code table7[]="012345";
- //uchar code table8[]="you did it! Do you think I will love you? no! What I love is not you,but all of you! I will love you forever!";
- uchar code table9[]=" You did it! ";
- uchar code table10[]=" Good! ";
- uchar code table11[]="The gift belongs";
- uchar code table12[]=" to you. ";
- uchar code table13[]=" I love you ";
- uchar code table14[]=" forever! ";
- sbit green=P3^2; //绿灯
- sbit blue=P3^3; //蓝灯
- sbit red=P3^4; //红灯
- sbit bao=P1^3; //蜂鸣器
- sbit jdq=P3^7; //继电器
- sbit en=P1^2; //定义LCD1602使能端
- sbit rw=P1^1;//定义LCD1602读/写选择端
- sbit rs=P1^0;//定义LCD1602数据/命令选择端
- uchar T1_NUM=0,T1_NUM1=0,T0_NUM=0,T0_NUM1=0;
- uchar j=0,k=0,h=0,y=0,l=0,z=0,flag=0,flag1=0,flag2=0,p=0,d=0;
- void delay (uchar del)
- {
- uint i,j;
- for(i=0;i<del;i++) //延时程序
- for(j=0;j<130;j++)
- ;
- }
- void lcd_wcom(uchar com)
- { rs=0; //选择指令寄存器
- rw=0; //选择写
- P0=com; //把命令字送入P0
- delay(10);
- en=0;
- delay(10); //延时一小会儿,让1602准备接收数据
- en=1;
- delay(10); //使能线电平变化,命令送入1602的8位数据口
- en=0;
- }
- void lcd_wdat(uchar dat) //1602写数据函数
- {
- rs=1; //选择数据寄存器
- rw=0; //选择写
- P0=dat; //把要显示的数据送入P2
- delay(10);
- en=0;
- delay(10); //延时一小会儿,让1602准备接收数据
- en=1;
- delay(10); //使能线电平变化,数据送入1602的8位数据口
- en=0;
- }
- void lcd_init()
- {
- lcd_wcom(0x38); //8位数据,双列,5*7字形
- lcd_wcom(0x0c); //开启显示屏,关光标,光标不闪烁
- lcd_wcom(0x06); //显示地址递减,即写一个数据后,显示位置右移一位
- lcd_wcom(0x01); //清屏
- }
- void xianshi()
- {
- uchar n,m=0;
- lcd_wcom(0x80+0x02); //显示地址上排第三位
- for(m=0;m<12;m++) //将table[]中的数据依次写入1602显示
- {
- lcd_wdat(table[m]);
- delay(5);
- }
- lcd_wcom(0x80+0x40);//显示地址为0xc4,即下排第1位
- for(n=0;n<8;n++) //将table1[]中的数据依次写入1602显示
- {
- lcd_wdat(table1[n]);
- delay(5);
- }
- }
- void xianshi1(uchar s)
- {
- uchar m;
- lcd_wcom(0x80+0x48); //显示地址上排第九位,显示输入的*号
- for(m=0;m<s;m++) //将table[]中的数据依次写入1602显示
- {
- lcd_wdat(table2[m]);
- delay(1);
- }
- }
- void xianshi2()
- {
- uchar m;
- lcd_wcom(0x80+0x48); //显示地址上排第九位,显示OK
- for(m=0;m<8;m++) //将table[]中的数据依次写入1602显示
- {
- lcd_wdat(table4[m]);
- delay(100);
- }
- }
- void xianshi3()
- {
- uchar m;
- lcd_wcom(0x80+0x48); //显示地址上排第九位,显示error
- for(m=0;m<8;m++) //将table[]中的数据依次写入1602显示
- {
- lcd_wdat(table3[m]);
- delay(100);
- }
- }
- void xianshi5()
- {
- uchar m=0;
- lcd_wcom(0x80+0x48); //显示地上排第九位,清除显示
- for(m=0;m<8;m++) //将table[]中的数据依次写入1602显示
- {
- lcd_wdat(table5[m]);
- delay(1);
- }
- }
- void xianshi6()
- {
- uchar m=0;
- lcd_wcom(0x80+0x00);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table9[m]);
- delay(100);
- }
- delay(100);
- lcd_wcom(0x80+0x40);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table10[m]);
- delay(100);
- }
- delay(100);
- lcd_wcom(0x80+0x00);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table11[m]);
- delay(100);
- }
- delay(100);
- lcd_wcom(0x80+0x40);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table12[m]);
- delay(100);
- }
- delay(100);
- lcd_wcom(0x80+0x00);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table13[m]);
- delay(100);
- }
- delay(100);
-
- lcd_wcom(0x80+0x40);
- for(m=0;m<16;m++)
- {
- lcd_wdat(table14[m]);
- delay(100);
- }
- delay(100);
- }
- void jishuqi( )
- {
- TMOD=0x10;
- TH1=(65536-40000)/256;
- TL1=(65536-40000)%256; //定时器T1,设置40ms
- ET1=1;
- EA=1;
- TR1=1;
-
- }
- void time1() interrupt 3
- {
- TH1=(65536-40000)/256;
- TL1=(65536-40000)%256;
- T1_NUM++;
- if(T1_NUM==25) //定时1S
- {
- T1_NUM=0;
- T1_NUM1++;
- p++;
- lcd_wcom(0x80+0x0f); //显示个位秒
- lcd_wdat(table6[p]);
- }
- if(T1_NUM1==5) //定时5S
- {
- T1_NUM1=0;
- if(flag==1)
- {
- red=~red;
- bao=1; //红灯状态反转
- flag=0;
- TR1=0;
- lcd_wcom(0x80+0x0e);
- lcd_wdat(table6[d]); //显示十位秒
- }
- }
- if(p==10)
- {
- p=0; //计时秒开始
- d++;
- if(d==6) //计时分开始
- d=0;
- }
- }
- void jishuqi1( )
- {
- TMOD=0x10;
- TH0=(65536-40000)/256;
- TL0=(65536-40000)%256; //定时器T1
- ET0=1;
- EA=1;
- TR0=1;
-
-
- }
- void time0() interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256; //设置50ms
- T0_NUM++;
- if(T0_NUM==100) //定时1S(正常来说T0_NUM应该=20就是1S,由于有误差,所以设置为100)
- {
-
- T0_NUM=0;
- T0_NUM1++;
- l++;
- if(l==10)
- {
- l=0; //个位定时
- z++;
- if(z==6) //十位定时
- z=0;
- }
- if(j-1!=flag2) //每1S检测是否有按键按下
- flag1=1; //没有按下,则赋值为1;
-
-
- }
- if(T0_NUM1==50) //定时50S
- {
- T0_NUM1=0;
- if(flag1>0&&flag1==1) //按键没有按下
- {
- flag1=0; //清零
- if(j==flag2&&P2==0xf0) //按键未操作且键盘按下次数未增加
- {
- red=0;
- delay(30);
- red=1; //超过50S未动作,清除数据并且清屏
- xianshi5();
- j=0;
- k=0;
- }
- }
- }
-
-
-
- }
- void key ()
- {
- uchar lie,jianzhi,szjianhao,szjianpan1,gnjianhao,caijimima[7],szjianhao2[7],sign,i;
- if(flag==1)
- {
- xianshi3();
- delay(100); //锁定键盘并且报警
- xianshi5();
-
- }
- else
- {
- P2=0xf0;
- if(P2!=0xf0)
- { //按键去抖动
- delay(10);
- if(P2!=0xf0)
- {
- j=j+1; //数字按键计数
- k=k+1; //功能按键计数
- lie=P2;
- P2=0x0f;
- jianzhi=lie|P2;
- for(i=0;i<10;i++)
- {
- if(jianzhi==szjianzhibiao[i])
- {
- szjianhao=szjianzhibiao[i]; //对比数字按键
- szjianpan1=i; //具体按键数字保存起来,可作用数码管显示,此可以不用理会
- sign=0; //是数字按键按下标记
- break;
- }
- }
- for(i=0;i<6;i++)
- {
- if(jianzhi==gnjianzhibiao[i])
- {
- gnjianhao=i; //对比功能按键
- sign=1; //是功能按键按下标记
- break;
- }
- }
- while(P2!=0x0f);
- delay(10);
-
- }
- if(sign==0) //数字按键按下判断
- {
- bao=0;
- delay(30); //蜂鸣器提示音
- bao=1;
- if(j==9) //连续九次输入数字按键
- {
- xianshi3();
- delay(30000);
- xianshi5();
- j=0;
- k=0; //错误提示、报警并且清除数据
- red=0;
- delay(150);
- red=1;
- for(i=0;i<8;i++)
- caijimima[i]=0;
- }
- else
- {
-
- for(i=j-1;i<j;i++)
- {
- caijimima[i]=szjianhao; //正确输入并且暂存储密码
- szjianhao2[i]=szjianpan1; //具体按键数字保存起来,可作用数码管显示,此可以不用理会
- green=0;
- delay(150);
- green=1;
- }
- xianshi1(i);
- }
- }
- if(sign==1) //功能按键判断
- {
- flag1=0;
- if(gnjianhao==3) //确认键判断
- {
- if(k==9)
- {
- for(i=0;i<8;i++)
- {
- if(mima[i]==caijimima[i])
- {
- h=h+1; //对比计数
- }
- else
- {
- h=1;
- break;
- }
- }
-
-
- if(h==8) //密码正确
- {
- k=0;
- j=0;
- h=0;
- blue=0;
- delay(150);
- blue=1;
- for(i=0;i<8;i++)
- caijimima[i]=0;
- xianshi2();
- delay(10000);
- xianshi5(); //开锁
- jdq=0;
- delay(100);
- jdq=1;
- lcd_wcom(0x01);
- xianshi6();
- lcd_wcom(0x01);
- xianshi();
-
-
- }
- if(h==1) //密码错误
- {
- bao=0;
- delay(200);
- bao=1;
- y++; //密码错误次数标记
- h=0;
- k=0;
- j=0;
- red=0;
- delay(150);
- red=1;
- for(i=0;i<8;i++)
- caijimima[i]=0;
- xianshi3();
- delay(30000);
- xianshi5();
- if(y==3)
- {
- y=0;
- red=0;
- flag=1; //三次密码错误,锁定键盘参数赋值
- bao=0;
- jishuqi(); //锁定10S计数开始
- }
-
- }
- }
- else
- {
- k=0;
- j=0;
- xianshi3();//请继续输入8位完整密码后在按确认键!
- delay(30000);
- xianshi5();
-
- }
- }
- if(gnjianhao==2) //清零键判断
- {
- for(i=0;i<7;i++)
- {
- caijimima[i]=0;
- }
- lcd_wcom(0x01);
- xianshi();
- k=0;
- j=0;
- }
- if(gnjianhao==1) //退格键判断
- {
- if(k==1&&j==1)
- {
- xianshi3();//错误,请输入8位完整密码!
- delay(30000);
- xianshi5();
-
- red=0;
- delay(200);
- red=1;
- delay(200);
- red=0;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
简单电子密码锁.7z
(962.95 KB, 下载次数: 32)
|