找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2623|回复: 1
打印 上一主题 下一主题
收起左侧

电子锁相关提问

[复制链接]
回帖奖励 5 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
这是网上找的一个电子锁程序,自己进行仿真了,但是输入密码环节不知道初始密码,也好像没法设定初始密码,有没有大神可以帮我看一下,是不是程序问题,还是我自己没搞懂?

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P1^2;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit p17=P1^7;      //开门指示:指示灯和蜂鸣器
uchar table1[8]={'N','A','M','E',':'};      //定义数码管的第一行"name: "
uchar table2[8]={'C','O','D','E',':'};       //定义数码管的第二行"lode: "
uchar name[10]={'0','1','2','3'};   
uchar cod[20]={'0','0','0','0','1','1','1','1','2','2','2','2','3','3','3','3'};    //定义四个用户,并设置对应的用户和密码,
                                          //其中用户0定义为超级用户0,用户1、用户2和用户3为普通用户
uint in_name;        //保存输入的用户名
uint error_num;          //输入密码错误的次数
uchar in_code1[4];        //保存第一次输入的密码
uchar in_code2[4];        //保存第二次输入的密码
uchar code sup[11]={'S','U','P','E','R',' ','U','S','E','R','!'};     //输入用户为超级用户
uchar code nor[12]={'N','O','R','M','A','L',' ','U','S','E','R','!'};    //输入用户为普通用户
uchar code err[6]={'E','R','R','O','R','!'};     //输入用户名或密码错误
uchar wait[8]={'W','A','I','T','I','N','G','!'};      //等待
uchar  aga[11]={'I','N','P','U','T',' ','A','G','A','I','N'};  //再次输入密码
uchar  ame[9]={'A','M','E','N','D','I','N','G','!'};     //正在修改密码
uchar  fun[6]={'a','b','c','d','e','f'};       //ABCDEF功能键
//====================延时函数======================//
void delay(uint x)
{
   uint a,b;
   for(a=x;a>0;a--)
     for(b=110;b>0;b--);
}
//=================1602写指令===============//
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
//==============1602写数据================//
void write_data(uchar dat)
{
lcdrs=1;
P0=dat;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
//===============1602在指定的位置显示一个字符=============//
void disp_char(uchar x,uchar y,uchar dat)
{
  uint i;
  uchar addr;
  if(y==1)
    addr=0x80+x;
  else
    addr=0xc0+x;
  write_com(addr);
    for(i=0;i<2;i++);
  write_data(dat);
    for(i=0;i<2;i++);
}
//==================1602数码管初始化函数==================//
void display()
{
lcden=0;
lcdrw=0;
write_com(0x38);  
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
//=============4*4键盘扫描函数=================//
uint keyscan()
{
   uchar temp;
   uint key=16;    //key=16表示没有按下任何键
   P2=0xfe;         //第一行被置为低电平,开始扫描第一行
   temp=P2;
   temp=temp&0xf0;               
   if(temp!=0xf0)
           {
             delay(1);
             temp=P2;
             temp=temp&0xf0;
             if(temp!=0xf0)
                     {
                              temp=P2;
                              switch(temp)
                              {
                               case(0xee):
                                         key=0;
                                         break;
                               case(0xde):
                                         key=1;
                                         break;
                               case(0xbe):
                                         key=2;
                                         break;
                               case(0x7e):
                                         key=3;
                                         break;
                              }
                              while(temp!=0xf0)    //等待按键释放
                              {
                               temp=P2;
                               temp=temp&0xf0;
                              }
                      }
           }

///////////////////////////////////////////  
   P2=0xfd;         //第二行被置为低电平,开始扫描第二行
   temp=P2;
   temp=temp&0xf0;
   if(temp!=0xf0)
   {
     delay(1);
     temp=P2;
     temp=temp&0xf0;
     if(temp!=0xf0)
     {
       temp=P2;
       switch(temp)
       {
        case(0xed):
                 key=4;
                 break;
        case(0xdd):
                 key=5;
                 break;
        case(0xbd):
                 key=6;
                 break;
        case(0x7d):
                 key=7;
                 break;
       }
       while(temp!=0xf0)    //等待按键释放
       {
       temp=P2;
       temp=temp&0xf0;
       }
     }
    }
////////////////////////////////////////
   P2=0xfb;         //第三行被置为低电平,开始扫描第三行
   temp=P2;
   temp=temp&0xf0;
   if(temp!=0xf0)
   {
     delay(1);
     temp=P2;
     temp=temp&0xf0;
     if(temp!=0xf0)
     {
       temp=P2;
       switch(temp)
       {
        case(0xeb):
                 key=8;
                 break;
        case(0xdb):
                 key=9;
                 break;
        case(0xbb):
                 key=10;
                 break;
        case(0x7b):
                 key=11;
                 break;
       }
       while(temp!=0xf0)    //等待按键释放
       {
         temp=P2;
         temp=temp&0xf0;
       }
     }
    }
//////////////////////////////////////////////  
   P2=0xf7;         //第四行被置为低电平,开始扫描第四行
   temp=P2;
   temp=temp&0xf0;
   if(temp!=0xf0)
   {
     delay(1);
     temp=P2;
     temp=temp&0xf0;
     if(temp!=0xf0)
     {
       temp=P2;
       switch(temp)
       {
        case(0xe7):
                 key=12;
                 break;
        case(0xd7):
                 key=13;
                 break;
        case(0xb7):
                 key=14;
                 break;
        case(0x77):
                 key=15;
                 break;
       }
       while(temp!=0xf0)    //等待按键释放
       {
       temp=P2;
       temp=temp&0xf0;
       }
     }
    }
    return(key);
}
/*/---------------B键的功能,删除用户--------------------//
void delete_user()
{

;

}
//--------------D键的功能,添加用户----------------------//
void add_user()
{



;


}                                 */
//----------------E键的功能,修改密码-------------//
void amend_code()  
{
  uint i,j,k=16;
    display();
        for(i=0;i<5;i++)
           disp_char(i,1,table1);    //第一行显示NAME:及对应的用户名
        disp_char(5,1,name[in_name]);
    for(i=0;i<5;i++)
          disp_char(i,2,table2);           //第二行显示CODE:AMENDING!
        for(i=0;i<9;i++)
          disp_char(i+5,2,ame);
  for(j=0;j<4;j++)
  {k=keyscan();
        while(k==16)
           k=keyscan();
        cod[in_name*4+i]=fun[k-10];
  }
}
//================F键的功能,开门,蜂鸣器间断响================//
void open_door()
{
   uint i,j;
   for(i=0;i<6;i++)
     for(j=0;j<10000;j++)
         {
           if((j/5000)%2==0)
             p17=1;
           else
             p17=0;
         }
     p17=0;
}
//===================超级用户相关操作======================//
void super_user()
{
   uint k=16;
   uint flag=0;
   while(flag==0)
   {
     k=keyscan();
     while(!(k==10||k==11||k==13||k==14||k==15))  //当A、B、D、E、F均未被按下时,继续扫描
       k=keyscan();
     if(k==10)     // 当A键被按下时,返回
       flag=1;
     if(k==11)     // 当B键被按下时,删除用户
     {
           flag=1;
//           delete_user();
         }
     if(k==13)           // 当D键被按下时,添加用户
     {
           flag=1;
//           add_user();
         }
     if(k==14)           // 当E键被按下时,修改密码
     {
           flag=1;
           amend_code();
         }
     if(k==15)          // 当F键被按下时,开门
     {
           flag=1;
           open_door();
         }
   }
     delay(6000);
}
//===================普通用户相关操作:改密、开门========================//
void normal_user()
{
  uint k=16;
  uint flag=0;
  while(flag==0)
  {
    k=keyscan();
    while(!(k==14||k==15))  //当没有按下E、F键时,继续扫描
      k=keyscan();  
    if(k==14);      //对应于E键
    {
           flag=1;            //普通用户完成一项操作
           amend_code();     //修改当前用户的密码
        }
    if(k==15)
        {
          flag=1;            //普通用户完成一项操作
      open_door();       //F键的功能,开门
        }
   }
   delay(6000);
}







//=================第二次输入密码函数====================//     
void input_code2()
{
  uint i,j,flag2=0;
  uint k2=16;        
  error_num=0;                          
  while(flag2==0&&error_num<3)
  {
    for(i=0;i<4;i++)     //输入4位数密码,保存在in_code2中
    {
     k2=keyscan();
         while(k2==16)
              k2=keyscan();         
     in_code2=fun[k2-10];
     display();
         for(j=0;j<5;j++)
            disp_char(j,1,table1[j]);    //第一行显示NAME:及对应的用户名
         disp_char(5,1,name[in_name]);
         for(j=0;j<5;j++)
                   disp_char(j,2,table2[j]);         //第二行先后显示CODE:*,CODE:**,CODE:***,CODE:****
         for(j=0;j<i+1;j++)
            disp_char(5+j,2,'*');
     delay(10);
    }
        delay(10);
//------检验输入的密码是否与第一次输入的密码一致-------//
    if(in_code2[0]==in_code1[0]&&in_code2[1]==in_code1[1]&&in_code2[2]==in_code1[2]&&in_code2[3]==in_code1[3])   
    {
           flag2=1;         //输入密码正确,退出while循环
           p17=1;                        //指示灯亮,蜂鸣器响,表示密码正确
           delay(400);
           p17=0;
        }
    else
        {
          flag2=0;         //输入密码错误重新输入
          error_num++;
      display();
          for(j=0;j<5;j++)                  //第一行显示NAME:及对应的用户名
             disp_char(j,1,table1[j]);
          disp_char(5,1,name[in_name]);
          for(j=0;j<5;j++)                          //第二行显示CODE:ERROR!2
             disp_char(j,2,table2[j]);
          for(j=0;j<6;j++)
                   disp_char(j+5,2,err[j]);
          disp_char(11,2,'2');
          delay(10);
         }
  }
}                           
//=================第一次输入密码函数====================//     
void input_code1()
{
  uint i,j,n,flag1=0,k1=16;
  error_num=0;
  while(flag1==0&&error_num<3)
  {
         for(i=0;i<4;i++)     //输入4位数密码,保存在in_code1中
   {
     k1=16;
     k1=keyscan();
         while(k1==16)
              k1=keyscan();   
     in_code1=fun[k1-10];
     display();
         for(j=0;j<5;j++)
            disp_char(j,1,table1[j]);    //第一行显示NAME:及对应的用户名
         disp_char(5,1,name[in_name]);
         for(j=0;j<5;j++)
                   disp_char(j,2,table2[j]);         //第二行先后显示CODE:*,CODE:**,CODE:***,CODE:****
         for(n=0;n<i+1;n++)
            disp_char(5+n,2,'*');
     delay(10);
   }
      delay(600);                           
//-------------检验输入的密码是否正确---------//
    if(in_code1[0]==cod[in_name*4+0]&&in_code1[1]==cod[in_name*4+1]&&in_code1[2]==cod[in_name*4+2]&&in_code1[3]==cod[in_name*4+3])   
    {
          flag1=1;     //输入密码正确,退出wlile循环,等待第二次输入密码
      display();
          for(j=0;j<5;j++)
            disp_char(j,1,table1[j]);    //第一行显示NAME:及对应的用户名
          disp_char(5,1,name[in_name]);         
          for(j=0;j<5;j++)
                   disp_char(j,2,table2[j]);         //第二行显示CODE:INPUT AGAIN
          for(j=0;j<11;j++)
                   disp_char(j+5,2,aga[j]);    //INPUT AGAIN
          delay(10);
          p17=0;                       //指示灯亮,蜂鸣器响,表示密码正确
          delay(400);
          p17=1;
        }  
    else
         {
          flag1=0;         //输入密码错误重新输入
          error_num++;
          display();
          for(j=0;j<5;j++)                  //第一行显示NAME:及对应的用户名
             disp_char(j,1,table1[j]);
          disp_char(5,1,name[in_name]);
          for(j=0;j<5;j++)                         //第二行显示CODE:ERROR!1
             disp_char(j,2,table2[j]);
          for(j=0;j<6;j++)
                   disp_char(j+5,2,err[j]);
          disp_char(11,2,'1');
          delay(100);
         }            
   }
}






//=================输入用户名函数===================//
void input_name()
{
  uint j,flag0=0,error_num=0;
  uint k0=16;                          
  while(flag0==0)         
  {
    k0=keyscan();
        while(k0==16)                 //k0=16表示未输入用户名
          k0=keyscan();
//-----------------------------//
    if(k0>=0&&k0<4)           //输入为用户0、用户1、用户2、用户3
    {
      flag0=1;                   //flag=1表示输入一个正确的用户
      in_name=k0;                  //记下所输入的正确用户的序号   
      display();            
          for(j=0;j<5;j++)                //第一行显示NAME:及输入的用户
             disp_char(j,1,table1[j]);
          disp_char(5,1,k0);
          for(j=0;j<5;j++)                         //第二行显示CODE:
             disp_char(j,2,table2[j]);
      delay(10);
          p17=0;                  //指示灯亮,蜂鸣器响,表示用户名正确
          delay(400);   
          p17=1;
    }                                
//-------------------------------//
   if((k0>=4&&k0<=15))   //输入的用户错误
   {
     flag0=0;
         error_num++;
     display();                  
          for(j=0;j<5;j++)                           //第一行显示NAME:ERROR!
             disp_char(j,1,table1[j]);
          disp_char(5,1,fun[k0-10]);
          for(j=0;j<6;j++)
             disp_char(j+7,1,err[j]);
          for(j=0;j<5;j++)                          //第二行显示CODE:
             disp_char(j,2,table2[j]);
      delay(10);
    }
  }                                          
}
void init()
{
  uint m;
  p17=0;
  display();     //等待输入用户名
  for(m=0;m<5;m++)
        disp_char(m,1,table1[m]);
  for(m=0;m<8;m++)
        disp_char(m+7,1,wait[m]);
  for(m=0;m<5;m++)                         //第二行显示CODE:
  disp_char(m,2,table2[m]);
  delay(10);
}
//====================主函数=====================//
void main()
{
  uint m;
  init();
  while(1)
  {
  input_name();            //进入用户名输入函数
  input_code1();               //用户名正确,接下来第一次输入密码
  if(error_num<3)
  {
    input_code2();               //第一次输入密码正确,第二次输入密码
        if(error_num<3)
        {
      if(in_name==0)
      {  
       // display();           
            for(m=0;m<5;m++)                                 //第一行显示NAME:及对应的用户名
              disp_char(m,1,table1[m]);   
            disp_char(5,1,name[in_name]);
            for(m=0;m<11;m++)                            //第二行显示输入用户为超级用户
              disp_char(m,2,sup[m]);
        delay(10);
        super_user();             //进入超级用户相关操作
     }
     else
     {
      // display();                             
            for(m=0;m<5;m++)                                  //第一行显示NAME:及对应的用户名
             disp_char(m,1,table1[m]);   
           disp_char(5,1,name[in_name]);      
           for(m=0;m<12;m++)                //第二行显示输入用户为普通用户
          disp_char(m,2,nor[m]);   
       delay(10);
       normal_user();              //进入普通用户相关操作
      }
        }
  }
          delay(500);
  }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2017-4-28 21:52 | 只看该作者
本帖最后由 zl2168 于 2017-4-29 11:03 编辑

网上乱七八糟的,大都有bug,看看我给你推荐的。


功能齐全的电子密码锁
电路设计   

功能设计   

程序设计   

Proteus仿真   
先Proteus仿真一下,确认有效,验证上述功能。
电子密码锁1.rar (1.13 MB, 下载次数: 12)
仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。



以上摘自张志良编著80C51单片机实用教程》ISBN978-7-04-044532-9,高教社出版。书中电路和程序设计有详细说明,程序语句条条有注解。


欢迎咨询,zzlls@126.com







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表