基于单片机的密码锁

从经济实用的角度出发,采用51单片机AT89S51与低功耗CMOS型E2PROM AT24C02作为主控芯片与数据存储器单元,结合外围的键盘输入、显示、报警、开锁等电路,用汇编语言编写主控芯片的控制程序,设计了一款可以多次更改密码具有报警功能的电子密码锁。
只实现简单通讯功能,能够处理下位机传上来的数据。继电器打开(开锁)上位机显示1;继电器关闭(关锁)上位机显示0。
本设计中的数据库、手动发送未用到。

使用数字小键盘输入六位密码
密码锁在输入密码正确的条件下输出开锁电平,控制电控锁开启
同时显示0【改成OK】字样
当输入密码错误时
发出错误警告声音
同时显示C【改成ERROR】字样
当六次误码【为简便改成三次】输入时产生报警信号
还可以实现对密码的修改
修改成功后蜂鸣发出确认音
电控锁开启
可以通过使步进电机转动180度来模拟开锁和关锁动作
LED【改用LCD】显示电子锁当前状态

/**************************************************************************************
                                         矩阵键盘:
                                         0      1      2       3
                                         
                                         4      5      6       7
                                                                                   
                                         8      9    返回    确定
                                         
                                         [        DISCUZ_CODE_1        ]nbsp;     [        DISCUZ_CODE_1        ]nbsp;     [        DISCUZ_CODE_1        ]nbsp;      [        DISCUZ_CODE_1        ]nbsp;                                                                                                                                                                 
***************************************************************************************/
#include "reg52.h"               
#include<intrins.h>                //左右移函数
#include "lcd.h"
#include "key.h"
#include "i2c.h"
#define u16 unsigned int  //对数据类型进行声明定义
#define u8 unsigned char
sbit AS=P2^2;               //继电器
sbit beep=P2^3;                                   //蜂鸣器
sbit MOTOA = P3^0;                        //步进电机
sbit MOTOB = P3^1;
sbit MOTOC = P3^2;
sbit MOTOD = P3^3;         
#define SPEED 200                         //步进电机脉冲
/*****************************************************************************/
u8 pw_num,Error_Num,Error_Num1,PassWord_Length=6;
u8 PASSWORD[]={8,8,8,8,8,8,0,0,0,0};
u8 INPUT_PW_Tab[10];
u8 key_num,Step,Step5,Load_first_flag=0;
u8 dianping;
/*******************************************************************************/
bit result_flag,Input_suc_flag;
bit List1=0;
/*******************************************************************************/
void Step_0();
void Step_1();
void Step_2();
void Step_3();
void Step_4();
         
void Step_5();
void Step5_0();
void Step5_1();
void Step5_2();
void Step5_3();
void Step5_4();
void Step5_5();
void Step_6();
/*******************************************************************************/
void CipherComparison();
void input_password(bit m);
void Read_Password();
void init_serialcomm( )
{
        EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
        ES = 1; //允许UART串口的中断
        TMOD = 0x20;        //定时器T/C1工作方式2
        SCON = 0x50;        //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
        TH1 = 0xF3;        //定时器初值高8位设置   //12MHZ晶振,波特率为4800 0xf3
        TL1 = 0xF3;        //定时器初值低8位设置   //11.0592MHZ晶振,波特率为4800 0xf4   9600  0xfa   19200  0xfd
        PCON = 0x80;        //波特率倍频(屏蔽本句波特率为2400)
        TR1 = 1;        //定时器启动
        TI = 1;  
}
void sendc(u8 ch)
{
        SBUF=ch;  
        while(!TI);
        TI=0;
}
void main()
{        
        u8 data1,a;
        //        ShowString(0x00," Pechin Science ");  
        //        At24c02Write(0,0);                                                //开机显示密码
        init_serialcomm();         /**************串口初始化*************/
        LcdWriteCom(0x01);  //清屏
        for(data1=0;data1<PassWord_Length+2;data1++)
        {
                a=At24c02Read(data1)+0x30;
                 LcdWriteData(a);        
                  delay(1000);        
     }
        
        delay(1000);
        LcdInit();
        delay(1000);
        Step=0;
        Step5=0;
        Error_Num=0x00;
        Error_Num1=0x00;
          Read_Password();
        
    //保存 密码长度
//                for(j=0;j<10;j++)
//                {
//                        At24c02Write(j,j);
//                        delay(100);        
//                }
//        
        while(1)
        {        
                key_num=KeyDown();                   //读取输入值
                switch(Step)
                {
                        case 0:
                        {Step_0();break;}
                        case 1:
                        {Step_1();break;}
                    case 2:
                    {Step_2();break;}
                        case 3:
                        {Step_3();break;}        
                        case 4:
                    {Step_4();break;}        
                        case 5:
                        {Step_5();break;}        
                        case 6:
                        {Step_6();break;}        
                                                                                                  
                }
     }                                
}
/*******************************************************************************/
void Step_0()
{
        LcdInit();
        ShowString(0x00," Pechin Science ");                   //第一行显示Pechin Science
        ShowString(0x10,"    WELCOME!    ");                   // 第二行显示 WELCOME!  
        while(KeyDown()==0xff)Step=1;                          //  有按键按下进入下一步                                 
}
/*******************************************************************************/
void Step_1()
{
                LcdWriteCom(0x01);                                           //清屏
          ShowString(0x00,"Unlock");
                ShowString(0x0f,"<");                                               //1602第一行显示unlock
          ShowString(0x10,"Change Password");
                ShowString(0x1f," ");                                                // 1602第二行显示Change Password                                                                                    
          Step=2;                                                              //
}
/*******************************************************************************/
void Step_2()
{
        if(key_num!=0x0b)  
        {
                if((key_num==0x01) ||( key_num==0x09))                    //1键或9键按下
                {
                        List1=~List1;                           //Change Password
                        if(List1==0)
                        {                                                  
                                ShowString(0x0f,"<");                           // Unlock            <
                                ShowString(0x1f," ");                                  // Change Password  
                        }
                        else
                        {
                                ShowString(0x0f," ");                           // Unlock            
                                ShowString(0x1f,"<");                                  // Change Password   <
                        }
                }
        }
        else                                                           //确认键按下
        {
                if(List1==0){Step=3;}
                else  {Step=5;List1=0;}
        }
}
/*******************************************************************************/
void Step_3()                                             
{
        Step=4;
        pw_num=0;
        LcdInit();
        ShowString(0x00,"Pass Word:  ");                                       
}
/*******************************************************************************/
void Step_4()                                                
{
         input_password(0);                                              //输入密码并以*显示
         if(Input_suc_flag==1){Step=6;}                                  //密码输入完成进入下一步
     Input_suc_flag=0;                                              //清除密码输入完成标志
}
/*******************************************************************************/
void Step_5()                                                        //修改密码
{
        switch(Step5)
        {
                        case 0: {Step5_0();}  break;
                        case 1: {Step5_1();}  break;
                        case 2: {Step5_2();}  break;
                        case 3: {Step5_3();}  break;
                    case 4: {Step5_4();}  break;
                        case 5:        {Step5_5();}  break;
        }
}
/*******************************************************************************/
void Step_6()
{        
        u8 i=0;
        u8 j=0;
        CipherComparison();                                //密码比对
        if(result_flag==1)                                 //密码正确
        {
                LcdInit();
                ShowString(0x00,"    WELCOME!");
                AS=0;                                         //开继电器
                dianping=1;//串口数据,表示锁开
                sendc(dianping);
                delay(SPEED);
                for(;j<5;j++)        
                {
                        MOTOA = 1;
                        MOTOB = 0;
                        MOTOC = 1;
                        MOTOD = 1;
                        delay(SPEED);
                        MOTOA = 1;
                        MOTOB = 1;
                        MOTOC = 1;
                        MOTOD = 0;
                        delay(SPEED);
                        MOTOA = 0;
                        MOTOB = 1;
                        MOTOC = 1;
                        MOTOD = 1;
                        delay(SPEED);
                        MOTOA = 1;
                        MOTOB = 1;
                        MOTOC = 0;
                        MOTOD = 1;
                        delay(SPEED);
                }
                delay(60000);
                AS=1;                                              //关继电器
                dianping=0;//串口数据,表示锁关        
                sendc(dianping);
                delay(SPEED);                                 
                for(j=0;j<5;j++)                                                                          //电机反转
                {
                        MOTOA = 1;
                        MOTOB = 1;
                        MOTOC = 0;
                        MOTOD = 1;
                        delay(SPEED);
                        MOTOA = 0;
                        MOTOB = 1;
                        MOTOC = 1;
                        MOTOD = 1;
                        delay(SPEED);
                        MOTOA = 1;
                        MOTOB = 1;
                        MOTOC = 1;
                        MOTOD = 0;
                        delay(SPEED);
               
                        MOTOA = 1;
                        MOTOB = 0;
                        MOTOC = 1;
                        MOTOD = 1;
                        delay(SPEED);
                }
        }
        else                                                //密码错误
        {
                        if(Error_Num1<2)             //输出错误次数小于3
                        {
                                        Error_Num1++;
                                        LcdInit();
                                        ShowString (0x00,"Error !");
                                        delay(20000);
                                        for(;i<200;i++)                                                        //密码错误报警
                                        {
                                                beep=~beep;
                                                delay(10);
                                                Step=0;
                                        }
                        else                          //密码错误次数大于3
                        {
                                        ShowString (0x00," Warning !");                                                               
                                        for(;i<250;i++)                        //防试探报警
                                        {
                                                beep=~beep;
                                                delay(50);
                                        }                                                                  
                                        Error_Num1=0;
                                        Step=0;
                        }
        }
        Step=0;
}
/****************************************************************************************
密码输入函数,密码长度:pw_num
密码输入完成标志:Input_suc_flag
*****************************************************************************************/
void Step5_0()                 
{
          LcdWriteCom(0x01);  //清屏
          ShowString (0x00,"Input PassWord:");     //1602显示:输入密码
          Step5=1;
          pw_num=0;
}
void Step5_1()               
{
        input_password(0);           //输入密码并以*显示
        if(Input_suc_flag==1)        //密码输入完成
        {
                Step5=2;                  
                Input_suc_flag=0;         //清除密码输入完成标志
        }
}
void Step5_2()               
{
     CipherComparison();          //密码比对
         Step5=3;
}
void Step5_3()               
{        u8 i=0;
    if(result_flag==0)            //密码错误
        {
                if(Error_Num<2)             //输出错误次数小于3
                {
                        Error_Num++;
                        LcdInit();
                        ShowString (0x00,"Error !");
                        delay(20000);
                        Step5=0;
                }
                else                          //密码错误次数大于3
                {
                        ShowString (0x00," Warning !");                                                               
                        for(;i<250;i++)                        //防试探报警
                        {
                                beep=~beep;
                                delay(50);
                        }                                                                  
                        Error_Num=0;
                        Step=0;
                }                        
        }
        else                                                                                                     //密码正确
        {
                LcdInit();
                ShowString (0x00,"New PassWord:");        
                pw_num=0;
                Step5=4;
        }                                
}
void Step5_4()
{
                u8 i=0;
                input_password(1);                                                    //输入密码并显示
                if(Input_suc_flag==1)                  //输入完成
                {
                                Step5=5;
                                Input_suc_flag=0;
                                LcdWriteCom(0x01);  //清屏
                                for(;i<100;i++)                //密码修改成功提示音
                                {
                                        beep=~beep;
                                        delay(10);
                                }  
                              ShowString (0x00,"      OK!");
                }
}
void Step5_5()
{
        unsigned char j;
        PassWord_Length=pw_num;                         //读取输入密码长度
        At24c02Write(0,Load_first_flag);        
        delay(100);        
        At24c02Write(1,PassWord_Length);                //保存 密码长度
        delay(100);
        for(j=0;j<PassWord_Length;j++)         
        {
                PASSWORD[j]=INPUT_PW_Tab[j];                                //读取密码
                At24c02Write(j+2,INPUT_PW_Tab[j]);                          //保存密码至EEPROM
                delay(100);
        }
        Step5=0;
        Step=0;
}
void Read_Password()
{
        unsigned char j;
        Load_first_flag=At24c02Read(0x00);
//        if(Load_first_flag==0)                          //初次运行  初始密码错误可以将此句打开重新编译下载
        {        
                Load_first_flag=1;
                At24c02Write(0,0x01);
                delay(100);
                At24c02Write(1,0x06);           //写默认密码长度6至EEPROM
                delay(100);
                for(j=0;j<PassWord_Length;j++)
                {
                        At24c02Write(j+2,8);              //写默认密码888888至EEPROM
                        PASSWORD[j]=INPUT_PW_Tab[j];     //读密码
                        delay(100);
                }
        }
        
        Load_first_flag=At24c02Read(0x00);
        PassWord_Length=At24c02Read(0x01);  //读取密码长度
        for(j=0;j<PassWord_Length;j++)       //读取密码
        {
                PASSWORD[j]=At24c02Read(j+2);
        }
}
void input_password(bit m)
{
        unsigned char j;
        if(key_num!=0x0b)                                      //ok键没有按下
        {
                if(key_num<0x0a)                               //1-9按下
                {
                        INPUT_PW_Tab[pw_num]=key_num;                //保存至输入密码数组
                        pw_num=pw_num+1;                              //密码长度+1
                                                
                        LcdWriteCom(0xc0);
                        for(j=0;j<pw_num;j++)
                        {
                                if(m==0) {LcdWriteData('*');        }                        //密码隐藏
                                else     {LcdWriteData(INPUT_PW_Tab[j]+0x30);}         //显示密码
                        }                                                               
                }
                if(key_num==0x0a)                              //返回键按下
                {
                        if(pw_num!=0) {pw_num=pw_num-1;}
                        else          {Step=0;}
                                                                        
                        // ShowString (0x00,"Pass Word:");  
            LcdWriteCom(0xc0);                                                
               
                        for(j=0;j<pw_num;j++)
                        {
                                if(m==0) {LcdWriteData('*');        }                   //密码隐藏
                                else     {LcdWriteData(INPUT_PW_Tab[j]+0x30);}    //显示密码        
                        }
                        LcdWriteData(' ');
                }
        }
        else                          //ok键按下
        {
                        if(pw_num==0)         
                        {
                                Step=0;
                                LcdWriteCom(0x01);
                                ShowString (0x00,"Error 02!");
                                delay(10000);
                        }
               
                        else
                        {               
                                Input_suc_flag=1;
                        }
                        //AS=0;                        
        }               
}
/*******************************************************
                密码比对
********************************************************/
void CipherComparison()
{
        u8 i,j=0;
        if(PassWord_Length==pw_num)                       //密码长度比对
        {
                for(i=0;i<PassWord_Length;i++)                  //密码比对
                {
                        
                                if(PASSWORD[i]!=INPUT_PW_Tab[i])
                                        {
                                                result_flag=0;break;                     //密码错误
                                        }
                                else
                                        {
                                                result_flag=1;                          //密码正确
                                        }
                                          INPUT_PW_Tab[i]=0XFF;                   //清除密码缓存数组
                }
        }
        else
        {result_flag=0;}
        
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/runweipa/article/details/139093945

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值