仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /*
- 上电显示8个*
- 输入8个按键
- 按*开锁
- 错误报警
- 再次按*修改密码
- 输入8个按键
- 按#保存密码
- 按*返回主菜单
- */
- #include<AT89x51.h>
- #include"intrins.h"
- #include"key.h"
- #include"xsh.h"
- #include"24c02.h"
- #include"1602.h"
- #define ulong unsigned long
- bit BJCB=0;//报警标志
- XG=0,//修改密码标志位
- BJ=0,//报警标志位
- SJ=0;//锁键盘标志位
- // xg=0;//修改密码标志位
- uchar PSWD0_0[16]={0};//密码输入缓存存储单元
- //uchar code PSWD0_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};//用户初始密码存储单元
- //uchar PSWD1_0[16]={0};//读出密码缓存存储单元
- uchar PSWD1_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};////管理员初始密码存储单元
- sbit OUT=P2^7;//输出端口
- sbit L1=P3^2;//上电指示
- sbit L2=P3^1;//开锁指示
- sbit L3=P3^0;//报警指示
- uint mg=0,//密码个数
- KSC=0,//开锁次数
- BJC=0,//报警次数
- TCNTY=0,//用户按键定时次数累加
- TCNTG=0,//管理员输入密码定时次数
- yhsh,//用户输入标志位
- glsh,//管理员输标志位
- shw;//密码输完标志位
- void yhmimaxig();//密码修改程序
- void glmimaxig();//管理员修改程序
- void bjyin(ulong t)
- {
- ulong c;
- uint n;
- for(c=0;c<t;c++)
- {
- for(n=0;n<50;n++); //延时
- BEEP=~BEEP; //取反输出到喇叭的信号
- }
- }
- void delay_10ms(void)
- {
- uint i = 1000;
- while(i--);
- }
- //////////////定时中断服务函数//////////////////////////////////////
- void timer0() interrupt 1
- {
- uint i;
- TH0=(65536-50000)/256; //对TH0 TL0赋值50MS定时
- TL0=(65536-50000)%256; //重装计数初值
- if(yhsh==1)
- {
- TCNTY++;//用户定时计数
- if(shw==1)
- {
- TR0=0;
- TCNTY=0;
- }
- if(TCNTY==400)
- {
- TR0=0;//关闭T0定时器
- TCNTY=0;
- mg=0;//密码个数清零
- L1=1;
- for(i=0;i<2;i++)//声光报警电路
- {
- L3=0;
- bjyin(1000);
- L3=1;
- delay(1000);
- }
- L1=0;
- }
- }
- else if(glsh==1)
- {
- TCNTG++;//管理员定时计数
- if(shw==1)
- {
- TR0=0;
- TCNTG=0;
- }
- if(TCNTG==400)
- {
- TR0=0;//关闭T0定时器
- TCNTG=0;
- mg=0;//密码个数清零
- L1=1;
- for(i=0;i<2;i++)//声光报警电路
- {
- L3=0;
- bjyin(1000);
- L3=1;
- delay(1000);
- }
- L1=0;
- }
- }
- }
-
- void main()
- { uint i;///////////密码输入/////////////////
- init_1602();
- /////////////////////////////开锁前显示///////////////////////////
- loop: L1=0;//上电红灯亮
- L2=1;//开锁成功后绿灯亮
- L3=1;//输错时黄灯亮报警
- OUT=0;//开信号关闭
- write_string(0,0,"qsrmm");
- write_com(0xc0);
- for(i=0;i<8;i++)
- {
- write_data(0x2a);
- }//开锁前显示
-
- ////////////////////密码输入///////////////////////////////////
- if(SJ==0)//锁键盘标志位为0
- {
- do
- {
- flag=0;//键盘标志位
- key();
- if(flag==1&&num<=9)
- {
- PSWD0_0[mg]=num;
- write_com(0xc0+mg);
- write_data(0x30+num);
- mg++;//密码个数
- }
- //删除未使用//
- if(flag==1&&num==14&&mg>=1)//输入错误删除
- {
- mg=mg-1;
- }
- if(mg==1) //有密码键按下开定时器限时
- {
- TR0=1;
- yhsh=1;
- }
- }
- while(num!=11);
- //////////////////密码比较////////////////////////
- if(flag==1&&num==11)
- { flag=0;
- yhsh=0;
- shw=1;
- num=0;
- for(i=0;i<8;i++) //从24c02里读出16个密码
- {
- PSWD1_1[i]=i2cRead24LC16B(i);
- delay_10ms;
- }
- for(i=0;i<8;i++)
- {
- if(PSWD1_1[i]!=PSWD0_0[i])
- {
- BJCB=1;
- break;
- }
- else
- BJCB=0;
-
- }
- /////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////
- //////////////////////报警/////////////////////////////////
- if(BJCB!=0)
- {
- BJC++;
- if(BJC!=3) //输错3次密码
- {
- BJCB=0; //第一次和第二次报警
- delay(500);
- mg=0;//密码个数清零
- L1=1;//上电指示
- for(i=0;i<3;i++)//声光报警电路
- {
- L3=0;//报警指示
- write_string(0,0,"mimacuowu BJ"); //显示报警
- bjyin(1000);
- L3=1;//报警指示
- delay(1000);
- }
- goto loop; //开锁前显示
- }
- //第三次输错密码//
- else if(BJC==3)
- {
- BJC=0;
- BJCB=0;
- write_string(0,0,"mima3cuowu BJ");//显示三次输入密码失败,自锁
- SJ=1;//锁键盘标志位
- mg=0;//密码个数清零
- L1=1;//上电
- for(i=0;i<2;i++)//声光报警电路
- {
- L3=0;//报警
- bjyin(1000);
- L3=1;
- delay(1000);
- }
- goto loop;
- }
- /////没有报警//
- }
- else
- if(BJCB==0)
- {
- KSC++;
- write_string(0,0,"ok-KS"); //显示开锁ok
- i2cWrite24LC16B(KSC,0X20);//写入开锁次数到24c01 0x20
- if(KSC==100)
- {
- SJ=1;
- }
- L2=0;//开锁成功后绿灯亮
- L1=1;
- OUT=1;//开信号打开
- mg=0;//密码个数清零
- loop1:do //键盘扫描等待功能键按下
- {
- flag=0;
- key();
- if(flag)
- {
- flag=0;
- switch(num)
- {
- case 11: //按#开始修改密码
- {
- write_string(0,0,"xg_mm");
- write_com(0xc0);
- for(i=0;i<8;i++)
- {
- write_data(0x2a);
- }//开锁前显示
- do
- {
- flag=0;//键盘标志位
- key();
- //修改密码
- if(flag==1&&num<=9)
- {
- PSWD0_0[mg]=num;
- write_com(0xc0+mg);
- write_data(0x30+num);
- mg++;//密码个数
- }
- if(mg==8)
- {
- do //键盘扫描等待功能键按下
- {
- flag=0;
- key();
- }
- while(num!=12);
- }
- }
- while(num!=12);
- if(mg!=8&&num==12)
- {
- for(i=mg;i<8;i++)
- {
- PSWD0_0[i]=0;
- }
- }
- if(flag==1&&num==12)
- {
- flag=0;
- mg=0;
- for(i=0;i<8;i++) //用一次写一个向24c02里写
- {
- i2cWrite24LC16B(PSWD0_0[i],i);
- delay_10ms;
- }
- write_string(0,1,"XG_OK "); //显示开锁ok
- delay(1000);
- goto loop;
-
- do //键盘扫描等待功能键按下
- {
- flag=0;
- key();
- }
- while(num!=11); //按下返回键,锁锁返回
- {
- goto loop;
- }
- }
- };break;
-
- }
- }
- }
- while(flag!=0);//如果设置密码键按下
- goto loop1;
- // i2cWrite24c02_page(0x00,PSWD1_1,mg);
- }
- }
- }
- }
复制代码
所有资料51hei提供下载:
8位密码锁ok.rar
(128.59 KB, 下载次数: 37)
|