|
所有资料下载:
单片机密码锁.zip
(4.71 MB, 下载次数: 150)
1. 电子密码锁采用51单片机作为主控芯片,4x4矩阵键盘作为输入设备,通过LCD1602显示,使用24C02芯片用于存储用户密码。
2.系统密码长度设置为7位,具有输入密码,更改密码,恢复初始密码功能,密码具有掉电存储功能。密码输入错误达到三次,则锁住键盘,并报警。
3.电子密码锁使用继电器进行模拟开锁过程。开锁声光提示。
密码锁的ppt教程:
原理图:
密码锁单片机程序源码:
- #include<reg52.h>
- #include<intrinS.h>
- #include<absacc.h>
- #include "keyc1.h" //见3.12
- #include "LCD1602.h"
- #include "24C02.h" //见2.2
- //见4.1
- #define unchar unsigned char
- #define uint unsigned int
-
- #define C02_write 0xa0
- #define C02_read 0xa1
- //----------------------------------------------------------------------------------------------
- #define enter 0x0c //确定
- #define backspace 0x0f //退格
- #define A 0x0a //输入密码
- #define B 0x0b //修改密码
- //-----------------------------------------------------------------------------------------------
- unchar idata temp5_password[6]=
- {0,0,0,0,0,0}; //设置初始密码为"123456"
- unchar num;//错误次数
- uint M1,M2=0,M3,M4,M5,M6;
- //-----------------------------------------------------------------------------------------------
- sbit SET=P3^2; //恢复出厂密码设置键
- sbit Lock_BIT=P2^0; //锁控制信号,输出低电平
- sbit SPK=P2^2; //报警信号输出端
- //-----------------------------------------------------------------------------------------------
- unchar int_count_1;
- unsigned int int_count_2;
- void SPKdelay(uint z) //蜂鸣器延时
- { uint i;
- for(i=z;i>0;i--);
- }
-
- //===============================================================================================
- void Longdelay(unsigned int i) //长时间延时函数
- {
- unsigned int j;
- for (;i>0;i--)
- for(j=10000;j>0;j--);
- }
-
- //================================================================================================
- bit compare_string(unchar *string1,unchar *string2)//密码对比函数
- {
- unchar count;//设置循环对比计数器
- for(count=0;count<6;count++)//设置要对比的密码为六位
- {
- if(string1[count]!=string2[count])
- return(0);//输入密码与原密码不相同时返回出错函数0
- }
- return(1);//输入密码正确返回正确参数1
- }
- //---------------------------------------------------------------------------------------------------
- unchar step_choose(void)//选择输入密码或修改密码处理函数
- {
- unsigned int i;
- unchar key;
- do{
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);//设置显示“input password”的地址
- Show_Char("Input Password");//显示"输入密码"
- GotoXY(0,1);//设置显示plaese press A的首地址
- Show_Char("Please Press A");//显示请输入A
- for(i=0;i<30000;i++)//循环读键盘
- {
- key=key1();//读键盘
- if((key==A)||(key==B)) break;//如果是A或B就退出
- }
- if((key!=A)&&(key!=B))//如果不是A也不是B,就执行下列程序
- {
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);// AC递增,画面不动
- GotoXY(0,0);//设置显示“input password”的地址
- Show_Char("Change Password");//显示修改密码
- GotoXY(0,1);//设置显示“please press B”的首地址
- Show_Char("Please Press B");//显示请输入B
- for(i=0;i<30000;i++)//循环读键盘
- {
- key=key1();//读键盘
- if((key==A)||(key==B)) break;//如果是A或B就退出
- }
- }
- }
- while((key!=A)&&(key!=B));//如果不是A也不是B,就循环读键盘
- return (key);//是A或B就带参数返回
- }
- //=================================================================================================
- bit input_password(unchar *password)//输入密码函数
- {
- unchar count,count1;//设置输入密码位数计数器
- unchar key;//设置键值变量
- GotoXY(0,1);
- for(count=0;count<7;count++)
- {
- Longdelay(3);//延时
- if(count<6);//输入密码小于六位吗?
- {
- do{key=key1();}//是的,读键盘
- while(key==0xff);//如果键盘值为0xff,继续读键盘
- if(key==0x0d) break; //退出键,回到初始界面
- if((key!=backspace)&&(key!=enter)&&(key>=0)&&(key<=9))//不是退格或确认键吗?
- {
- Show_1_Char('*');//不是,是数字键就显示'*'号
- password[count]=key;//键值送入输入密码数组对应位
- }
- if(key==backspace)//是退格键吗?
- {
- if(count>0)//输入位数大于0吗?
- {
- GotoXY(--count,1);//是的,送删除位的显示地址
- Show_1_Char(' '); //删除位显示空白
- password[count]=' '; //输入密码数组对应位置空白
- GotoXY(count,1); //送闪烁位
- count--;//密码位计数器减1
-
- }
- }
- if(key==enter)//是确认键吗
- {
- GotoXY(0,0);//是的,改变显示首地址
- return(0);//返回出错参数0
- }
- }
- if(count==6)//密码位计数器等于6吗
- {
- do{key=key1();}//等于6,读键盘
- while((key!=backspace)&&(key!=enter));//不是退格键或确认键,继续读键盘
- if(key==backspace)//是退格键吗
- {
- GotoXY(--count,1);//是的,送删除位的显示地址
- Show_1_Char(' ');//删除位显示空白
- GotoXY(count,1);//送闪烁位
- count--;//密码位计数器减1
- }
- if(key==enter)//是确认键吗
- {return(1);}//是的,输入密码完成,返回正确参数1
- }
- }
- }
- //===================================================================================================
- void password()//密码处理函数
- {
- uchar key,key2;
- uint kscount=0;
- unchar idata temp1_password[6]={' ',' ',' ',' ',' ',' '};//设置4组6位密码变量
- unchar idata temp3_password[6]={' ',' ',' ',' ',' ',' '}; //初始化为空白
- unchar idata temp2_password[6]={' ',' ',' ',' ',' ',' '};
- unchar idata temp4_password[6]={' ',' ',' ',' ',' ',' '};
- key=step_choose( );//读选择状态
- if(key==A)//是选择输入密码吗?
- {
- Read_Flash(temp1_password,0x00,6);//是的从24c02中读取密码送入第一组密码变量中
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);//设置显示“input password”的首地址
- Show_Char("Input Password");//显示“输入密码”
- if(input_password(temp2_password))//完成输入密码了吗?
- {
- if(compare_string(temp1_password,temp2_password))//完成,比较密码正确吗
- { num=0;
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);//正确,设置显示“password correct”的首地址
- Show_Char("Password Correct");//显示"密码正确"
- GotoXY(0,1);//正确,设置显示“password correct”的首地址
- Show_Char("Open Lock");//显示"密码正确" Lock_BIT=0;//密码正确,开锁
- Lock_BIT=0;//关开锁信号
- while(1)
- {
- kscount++;
- if(kscount==1000)
- break;
- SPK=0;
- SPKdelay(10);//发开锁提示声
- SPK=1;
- SPKdelay(40);
- }
-
- while(1)
- { key2=key1();
- if(key2==0x0e)
- {
- Lock_BIT=1;//关开锁信号
- break;
- }
- }
- SPK=0;
- //关开锁提示音
- TR0=0;//关定时器0
- return;//返回
- }
- else
- {
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);//错误,设置显示“wrong password”的首地址
- Show_Char("Wrong Password");//显示“密码错误”
- Longdelay(25);
- num++;
- if(num==3)
- {
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);
- Show_Char("Please Wait For");
- GotoXY(0,1);
- Show_Char(" 3 Minute");
- while(1)
- {
- SPK=0;
- SPKdelay(100);
- SPK=1;
- SPKdelay(100);
- M1++;
- if(M1==24000)
- {
- break;
- }
- }
- Longdelay(1400);
- }
- Longdelay(10);//延时
- return;//返回
- }
- }
- else
- {
- GotoXY(0,1);//没有完成密码输入,设置显示“error!”的首地址
- Show_Char("Error!");//显示“出错”
- Longdelay(15);//延时
- }
- }
- else//是,修改密码
- {
- Read_Flash(temp1_password,0x00,6);//从24c02中读取密码送入第一组密码变量中
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);//设置显示“input old password”的首地址
- Show_Char("Input Old Password");//显示输入旧密码
- if(input_password(temp2_password))//完成输入密码了吗(输入的旧密码放在数组2中)
- {
- if(compare_string(temp1_password,temp2_password))//完成,比较密码正确吗?
- {
- GotoXY(0,1);//正确,设置显示“password correct!”的首地址
- Show_Char("Password Correct!");//显示“密码正确”
- Longdelay(6);//延时
- WR_CMD(0x01);
- WR_CMD(0x06);
- GotoXY(0,0);
- Show_Char("Input New Password!");
- if(input_password(temp3_password))//完成第一次新密码输入吗?(输入密码放在数组三中)
- {
- WR_CMD(0x01);
- WR_CMD(0x06);
- GotoXY(0,0);
- Show_Char("Input Again");//显示再次输入密码
- if(input_password(temp4_password))//完成第二次新密码输入吗?(输入的密码放在密码组4中)
- {
- if(compare_string(temp3_password,temp4_password))//比较两次输入密码属否相同
- {
- Write_Flash(temp3_password,0x00,6);//相同,将新密码存入24c02中
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);
- Show_Char("Password has");
- GotoXY(0,1);
- Show_Char("been changed");
- Longdelay(10);
- return;
- }
- else
- {
- WR_CMD(0x01);//两次输入不同清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);
- Show_Char("Twice input"); //显示”两次输入“
- GotoXY(0,1);
- Show_Char("is different"); //显示是“不同的”
- Longdelay(10);
- return;
- }
- }
- else
- {
- GotoXY(0,1);//没有正确完成第二次新密码的输入,设置显示“error”的首地址
- Show_Char("Error!");//显示错误
- Longdelay(15);
- return;
- }
- }
- else
- {
- GotoXY(0,1);//没有正确完成第一次新密码输入,设置显示“error”的首地址
- Show_Char("Error!");
- Longdelay(15);
- return;
- }
- }
- else
- {
- WR_CMD(0x01);//两次输入不同清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(3,0);//旧密码输入错误,设置显示“wrong password”的首地址
- Show_Char("Sorry");
- GotoXY(0,1);
- Show_Char("Wrong password");
- num++;
- if(num==3)
- {
- WR_CMD(0x01);//清屏
- WR_CMD(0x06);//AC递增,画面不动
- GotoXY(0,0);
- Show_Char("Please Wait For");
- GotoXY(0,1);
- Show_Char(" 3 Minute");
- while(1)
- {
- SPK=0;
- SPKdelay(100);
- SPK=1;
- SPKdelay(100);
- M1++;
- if(M1==24000)
- {
- break;
- }
- }
- Longdelay(1400);
- }
- Longdelay(25);
- return;
- }
- }
- else
- {
- GotoXY(0,1);//没有正确完成旧密码的输入,设置显示“error!”的首地址
- Show_Char("Error!");
- Longdelay(15);
- return;
- }
- }
- }
- //============================================================================================================
- void int_service(void) interrupt 0 //外部中断0处理函数
- {
- EA=1;//关CPU中断
- EX0=1;//关外部中断0
- for(int_count_1=4;int_count_1>0;int_count_1--)//设置延时时间,10秒
- {
- for(int_count_2=0xffff;int_count_2>0;int_count_2--)
- {
- if(SET==1)//恢复出厂密码设置键松开否?
- {
- return;
- }
- }
- }
- WR_CMD(0x01);
- WR_CMD(0x06);
- Show_Char("Reset Cuccess!");//显示“恢复出厂密码”
- Longdelay(50);
- Write_Flash(temp5_password,0x00,6); //初始密码0000000密码送入24c02中保存
-
- /* EA=1;//关CPU中断
- EX0=1; */
- }
- //==========================================================================================
- void t0(void) interrupt 1 using 0//定时、计数器0中断处理函数
- {
- TH0=(65536-1000)/256;//重新将定时1000微秒初值的高八位送入TH0
- TL0=(65536-1000)%256;// 重新将定时1000微秒初值的低八位送入TL0
- SPK=~SPK;//信号输出位取反,即1000微秒反转一次,产生周期为2ms的方波
- }
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- main()
- { unchar key;
- Initialize(); //1602初始化
- IT0=1;//设INT0为跳变沿沿触发方式
- EX0=1;//开外部中断0
- TMOD=0x01;
- TH0=(65536-1000)/256;//重新将定时1000微秒初值的高八位送入TH0
- TL0=(65536-1000)%256;// 重新将定时1000微秒初值的低八位送入TL0
- TR0=0;
- ET0=1;
- EA=1;
- while(1)
- {
- password();//运行密码处理函数
- }
- }
- //=================================终于完成了==================================================
复制代码
|
|