找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 466|回复: 1
收起左侧

单片机密码锁仿真程序 VB上位机

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

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

VB上位机
51hei.png
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

单片机源程序如下:
  1. /**************************************************************************************
  2.                                          矩阵键盘:
  3.                                          0      1      2       3
  4.                                          
  5.                                          4      5      6       7
  6.                                                                                    
  7.                                          8      9    返回    确定
  8.                                          
  9.                                          [        DISCUZ_CODE_1        ]nbsp;     [        DISCUZ_CODE_1        ]nbsp;     [        DISCUZ_CODE_1        ]nbsp;      [        DISCUZ_CODE_1        ]nbsp;                                                                                                                                                                 
  10. ***************************************************************************************/

  11. #include "reg52.h"               
  12. #include<intrins.h>                //左右移函数
  13. #include "lcd.h"
  14. #include "key.h"
  15. #include "i2c.h"

  16. #define u16 unsigned int  //对数据类型进行声明定义
  17. #define u8 unsigned char

  18. sbit AS=P2^2;               //继电器
  19. sbit beep=P2^3;                                   //蜂鸣器

  20. sbit MOTOA = P3^0;                        //步进电机
  21. sbit MOTOB = P3^1;
  22. sbit MOTOC = P3^2;
  23. sbit MOTOD = P3^3;         

  24. #define SPEED 200                         //步进电机脉冲

  25. /*****************************************************************************/
  26. u8 pw_num,Error_Num,Error_Num1,PassWord_Length=6;
  27. u8 PASSWORD[]={8,8,8,8,8,8,0,0,0,0};
  28. u8 INPUT_PW_Tab[10];
  29. u8 key_num,Step,Step5,Load_first_flag=0;
  30. u8 dianping;

  31. /*******************************************************************************/
  32. bit result_flag,Input_suc_flag;
  33. bit List1=0;

  34. /*******************************************************************************/
  35. void Step_0();
  36. void Step_1();
  37. void Step_2();
  38. void Step_3();
  39. void Step_4();
  40.          
  41. void Step_5();
  42. void Step5_0();
  43. void Step5_1();
  44. void Step5_2();
  45. void Step5_3();
  46. void Step5_4();
  47. void Step5_5();
  48. void Step_6();

  49. /*******************************************************************************/
  50. void CipherComparison();
  51. void input_password(bit m);
  52. void Read_Password();

  53. void init_serialcomm( )
  54. {
  55.         EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
  56.         ES = 1; //允许UART串口的中断

  57.         TMOD = 0x20;        //定时器T/C1工作方式2
  58.         SCON = 0x50;        //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
  59.         TH1 = 0xF3;        //定时器初值高8位设置   //12MHZ晶振,波特率为4800 0xf3
  60.         TL1 = 0xF3;        //定时器初值低8位设置   //11.0592MHZ晶振,波特率为4800 0xf4   9600  0xfa   19200  0xfd
  61.         PCON = 0x80;        //波特率倍频(屏蔽本句波特率为2400)
  62.         TR1 = 1;        //定时器启动
  63.         TI = 1;  
  64. }

  65. void sendc(u8 ch)
  66. {
  67.         SBUF=ch;  
  68.         while(!TI);
  69.         TI=0;
  70. }

  71. void main()
  72. {        
  73.         u8 data1,a;
  74.         //        ShowString(0x00," Pechin Science ");  
  75.         //        At24c02Write(0,0);                                                //开机显示密码
  76.         init_serialcomm();         /**************串口初始化*************/
  77.         LcdWriteCom(0x01);  //清屏
  78.         for(data1=0;data1<PassWord_Length+2;data1++)
  79.         {
  80.                 a=At24c02Read(data1)+0x30;
  81.                  LcdWriteData(a);        
  82.                   delay(1000);        
  83.      }
  84.         
  85.         delay(1000);
  86.         LcdInit();
  87.         delay(1000);
  88.         Step=0;
  89.         Step5=0;
  90.         Error_Num=0x00;
  91.         Error_Num1=0x00;
  92.           Read_Password();
  93.         
  94.     //保存 密码长度
  95. //                for(j=0;j<10;j++)
  96. //                {
  97. //                        At24c02Write(j,j);
  98. //                        delay(100);        
  99. //                }
  100. //        

  101.         while(1)
  102.         {        
  103.                 key_num=KeyDown();                   //读取输入值
  104.                 switch(Step)
  105.                 {
  106.                         case 0:
  107.                         {Step_0();break;}
  108.                         case 1:
  109.                         {Step_1();break;}
  110.                     case 2:
  111.                     {Step_2();break;}
  112.                         case 3:
  113.                         {Step_3();break;}        
  114.                         case 4:
  115.                     {Step_4();break;}        
  116.                         case 5:
  117.                         {Step_5();break;}        
  118.                         case 6:
  119.                         {Step_6();break;}        
  120.                                                                                                   
  121.                 }
  122.      }                                
  123. }

  124. /*******************************************************************************/
  125. void Step_0()
  126. {
  127.         LcdInit();
  128.         ShowString(0x00," Pechin Science ");                   //第一行显示Pechin Science
  129.         ShowString(0x10,"    WELCOME!    ");                   // 第二行显示 WELCOME!  
  130.         while(KeyDown()==0xff)Step=1;                          //  有按键按下进入下一步                                 
  131. }

  132. /*******************************************************************************/
  133. void Step_1()
  134. {
  135.                 LcdWriteCom(0x01);                                           //清屏
  136.           ShowString(0x00,"Unlock");
  137.                 ShowString(0x0f,"<");                                               //1602第一行显示unlock
  138.           ShowString(0x10,"Change Password");
  139.                 ShowString(0x1f," ");                                                // 1602第二行显示Change Password                                                                                    
  140.           Step=2;                                                              //
  141. }

  142. /*******************************************************************************/
  143. void Step_2()
  144. {
  145.         if(key_num!=0x0b)  
  146.         {
  147.                 if((key_num==0x01) ||( key_num==0x09))                    //1键或9键按下
  148.                 {
  149.                         List1=~List1;                           //Change Password
  150.                         if(List1==0)
  151.                         {                                                  
  152.                                 ShowString(0x0f,"<");                           // Unlock            <
  153.                                 ShowString(0x1f," ");                                  // Change Password  
  154.                         }
  155.                         else
  156.                         {
  157.                                 ShowString(0x0f," ");                           // Unlock            
  158.                                 ShowString(0x1f,"<");                                  // Change Password   <
  159.                         }
  160.                 }
  161.         }
  162.         else                                                           //确认键按下
  163.         {
  164.                 if(List1==0){Step=3;}
  165.                 else  {Step=5;List1=0;}
  166.         }
  167. }

  168. /*******************************************************************************/
  169. void Step_3()                                             
  170. {
  171.         Step=4;
  172.         pw_num=0;
  173.         LcdInit();
  174.         ShowString(0x00,"Pass Word:  ");                                       
  175. }

  176. /*******************************************************************************/
  177. void Step_4()                                                
  178. {
  179.          input_password(0);                                              //输入密码并以*显示
  180.          if(Input_suc_flag==1){Step=6;}                                  //密码输入完成进入下一步
  181.      Input_suc_flag=0;                                              //清除密码输入完成标志
  182. }

  183. /*******************************************************************************/
  184. void Step_5()                                                        //修改密码
  185. {
  186.         switch(Step5)
  187.         {
  188.                         case 0: {Step5_0();}  break;
  189.                         case 1: {Step5_1();}  break;
  190.                         case 2: {Step5_2();}  break;
  191.                         case 3: {Step5_3();}  break;
  192.                     case 4: {Step5_4();}  break;
  193.                         case 5:        {Step5_5();}  break;
  194.         }
  195. }

  196. /*******************************************************************************/
  197. void Step_6()
  198. {        
  199.         u8 i=0;
  200.         u8 j=0;
  201.         CipherComparison();                                //密码比对
  202.         if(result_flag==1)                                 //密码正确
  203.         {
  204.                 LcdInit();
  205.                 ShowString(0x00,"    WELCOME!");
  206.                 AS=0;                                         //开继电器
  207.                 dianping=1;//串口数据,表示锁开
  208.                 sendc(dianping);
  209.                 delay(SPEED);
  210.                 for(;j<5;j++)        
  211.                 {
  212.                         MOTOA = 1;
  213.                         MOTOB = 0;
  214.                         MOTOC = 1;
  215.                         MOTOD = 1;
  216.                         delay(SPEED);

  217.                         MOTOA = 1;
  218.                         MOTOB = 1;
  219.                         MOTOC = 1;
  220.                         MOTOD = 0;
  221.                         delay(SPEED);

  222.                         MOTOA = 0;
  223.                         MOTOB = 1;
  224.                         MOTOC = 1;
  225.                         MOTOD = 1;
  226.                         delay(SPEED);

  227.                         MOTOA = 1;
  228.                         MOTOB = 1;
  229.                         MOTOC = 0;
  230.                         MOTOD = 1;
  231.                         delay(SPEED);
  232.                 }

  233.                 delay(60000);
  234.                 AS=1;                                              //关继电器
  235.                 dianping=0;//串口数据,表示锁关        
  236.                 sendc(dianping);
  237.                 delay(SPEED);                                 
  238.                 for(j=0;j<5;j++)                                                                          //电机反转
  239.                 {
  240.                         MOTOA = 1;
  241.                         MOTOB = 1;
  242.                         MOTOC = 0;
  243.                         MOTOD = 1;
  244.                         delay(SPEED);

  245.                         MOTOA = 0;
  246.                         MOTOB = 1;
  247.                         MOTOC = 1;
  248.                         MOTOD = 1;
  249.                         delay(SPEED);

  250.                         MOTOA = 1;
  251.                         MOTOB = 1;
  252.                         MOTOC = 1;
  253.                         MOTOD = 0;
  254.                         delay(SPEED);
  255.                
  256.                         MOTOA = 1;
  257.                         MOTOB = 0;
  258.                         MOTOC = 1;
  259.                         MOTOD = 1;
  260.                         delay(SPEED);
  261.                 }
  262.         }
  263.         else                                                //密码错误
  264.         {
  265.                         if(Error_Num1<2)             //输出错误次数小于3
  266.                         {
  267.                                         Error_Num1++;
  268.                                         LcdInit();
  269.                                         ShowString (0x00,"Error !");
  270.                                         delay(20000);
  271.                                         for(;i<200;i++)                                                        //密码错误报警
  272.                                         {
  273.                                                 beep=~beep;
  274.                                                 delay(10);
  275.                                                 Step=0;
  276.                                         }
  277.                         else                          //密码错误次数大于3
  278.                         {
  279.                                         ShowString (0x00," Warning !");                                                               
  280.                                         for(;i<250;i++)                        //防试探报警
  281.                                         {
  282.                                                 beep=~beep;
  283.                                                 delay(50);
  284.                                         }                                                                  
  285.                                         Error_Num1=0;
  286.                                         Step=0;
  287.                         }
  288.         }
  289.         Step=0;
  290. }

  291. /****************************************************************************************
  292. 密码输入函数,密码长度:pw_num
  293. 密码输入完成标志:Input_suc_flag
  294. *****************************************************************************************/
  295. void Step5_0()                 
  296. {
  297.           LcdWriteCom(0x01);  //清屏
  298.           ShowString (0x00,"Input PassWord:");     //1602显示:输入密码
  299.           Step5=1;
  300.           pw_num=0;
  301. }
  302. void Step5_1()               
  303. {
  304.         input_password(0);           //输入密码并以*显示
  305.         if(Input_suc_flag==1)        //密码输入完成
  306.         {
  307.                 Step5=2;                  
  308.                 Input_suc_flag=0;         //清除密码输入完成标志
  309.         }
  310. }
  311. void Step5_2()               
  312. {
  313.      CipherComparison();          //密码比对
  314.          Step5=3;
  315. }
  316. void Step5_3()               
  317. {        u8 i=0;
  318.     if(result_flag==0)            //密码错误
  319.         {
  320.                 if(Error_Num<2)             //输出错误次数小于3
  321.                 {
  322.                         Error_Num++;
  323.                         LcdInit();
  324.                         ShowString (0x00,"Error !");
  325.                         delay(20000);
  326.                         Step5=0;
  327.                 }
  328.                 else                          //密码错误次数大于3
  329.                 {
  330.                         ShowString (0x00," Warning !");                                                               
  331.                         for(;i<250;i++)                        //防试探报警
  332.                         {
  333.                                 beep=~beep;
  334.                                 delay(50);
  335.                         }                                                                  
  336.                         Error_Num=0;
  337.                         Step=0;
  338.                 }                        
  339.         }
  340.         else                                                                                                     //密码正确
  341.         {
  342.                 LcdInit();
  343.                 ShowString (0x00,"New PassWord:");        
  344.                 pw_num=0;
  345.                 Step5=4;
  346.         }                                
  347. }
  348. void Step5_4()
  349. {
  350.                 u8 i=0;
  351.                 input_password(1);                                                    //输入密码并显示
  352.                 if(Input_suc_flag==1)                  //输入完成
  353.                 {
  354.                                 Step5=5;
  355.                                 Input_suc_flag=0;
  356.                                 LcdWriteCom(0x01);  //清屏
  357.                                 for(;i<100;i++)                //密码修改成功提示音
  358.                                 {
  359.                                         beep=~beep;
  360.                                         delay(10);
  361.                                 }  
  362.                               ShowString (0x00,"      OK!");
  363.                 }
  364. }
  365. void Step5_5()
  366. {
  367.         unsigned char j;
  368.         PassWord_Length=pw_num;                         //读取输入密码长度
  369.         At24c02Write(0,Load_first_flag);        
  370.         delay(100);        
  371.         At24c02Write(1,PassWord_Length);                //保存 密码长度
  372.         delay(100);
  373.         for(j=0;j<PassWord_Length;j++)         
  374.         {
  375.                 PASSWORD[j]=INPUT_PW_Tab[j];                                //读取密码
  376.                 At24c02Write(j+2,INPUT_PW_Tab[j]);                          //保存密码至EEPROM
  377.                 delay(100);
  378.         }
  379.         Step5=0;
  380.         Step=0;
  381. }

  382. void Read_Password()
  383. {
  384.         unsigned char j;
  385.         Load_first_flag=At24c02Read(0x00);
  386. //        if(Load_first_flag==0)                          //初次运行  初始密码错误可以将此句打开重新编译下载
  387.         {        
  388.                 Load_first_flag=1;
  389.                 At24c02Write(0,0x01);
  390.                 delay(100);
  391.                 At24c02Write(1,0x06);           //写默认密码长度6至EEPROM
  392.                 delay(100);
  393.                 for(j=0;j<PassWord_Length;j++)
  394.                 {
  395.                         At24c02Write(j+2,8);              //写默认密码888888至EEPROM
  396.                         PASSWORD[j]=INPUT_PW_Tab[j];     //读密码
  397.                         delay(100);
  398.                 }
  399.         }
  400.         
  401.         Load_first_flag=At24c02Read(0x00);
  402.         PassWord_Length=At24c02Read(0x01);  //读取密码长度
  403.         for(j=0;j<PassWord_Length;j++)       //读取密码
  404.         {
  405.                 PASSWORD[j]=At24c02Read(j+2);
  406.         }
  407. }
  408. void input_password(bit m)
  409. {
  410.         unsigned char j;
  411.         if(key_num!=0x0b)                                      //ok键没有按下
  412.         {
  413.                 if(key_num<0x0a)                               //1-9按下
  414.                 {
  415.                         INPUT_PW_Tab[pw_num]=key_num;                //保存至输入密码数组
  416.                         pw_num=pw_num+1;                              //密码长度+1
  417.                                                 
  418.                         LcdWriteCom(0xc0);
  419.                         for(j=0;j<pw_num;j++)
  420.                         {
  421.                                 if(m==0) {LcdWriteData('*');        }                        //密码隐藏
  422.                                 else     {LcdWriteData(INPUT_PW_Tab[j]+0x30);}         //显示密码
  423.                         }                                                               
  424.                 }
  425.                 if(key_num==0x0a)                              //返回键按下
  426.                 {
  427.                         if(pw_num!=0) {pw_num=pw_num-1;}
  428.                         else          {Step=0;}
  429.                                                                         
  430.                         // ShowString (0x00,"Pass Word:");  
  431.             LcdWriteCom(0xc0);                                                
  432.                
  433.                         for(j=0;j<pw_num;j++)
  434.                         {
  435.                                 if(m==0) {LcdWriteData('*');        }                   //密码隐藏
  436.                                 else     {LcdWriteData(INPUT_PW_Tab[j]+0x30);}    //显示密码        
  437.                         }
  438.                         LcdWriteData(' ');
  439.                 }
  440.         }
  441.         else                          //ok键按下
  442.         {
  443.                         if(pw_num==0)         
  444.                         {
  445.                                 Step=0;
  446.                                 LcdWriteCom(0x01);
  447.                                 ShowString (0x00,"Error 02!");
  448.                                 delay(10000);
  449.                         }
  450.                
  451.                         else
  452.                         {               
  453.                                 Input_suc_flag=1;
  454.                         }
  455.                         //AS=0;                        
  456.         }               
  457. }

  458. /*******************************************************
  459.                 密码比对
  460. ********************************************************/
  461. void CipherComparison()
  462. {
  463.         u8 i,j=0;

  464.         if(PassWord_Length==pw_num)                       //密码长度比对
  465.         {
  466.                 for(i=0;i<PassWord_Length;i++)                  //密码比对
  467.                 {
  468.                         
  469.                                 if(PASSWORD[i]!=INPUT_PW_Tab[i])
  470.                                         {
  471.                                                 result_flag=0;break;                     //密码错误
  472.                                         }
  473.                                 else
  474.                                         {
  475.                                                 result_flag=1;                          //密码正确
  476.                                         }
  477.                                           INPUT_PW_Tab[i]=0XFF;                   //清除密码缓存数组
  478.                 }
  479.         }
  480.         else
  481.         {result_flag=0;}
  482.         
  483. }
复制代码

所有资料51hei附件下载:
电子密码锁51单片机设计(实物 仿真).7z (186.5 KB, 下载次数: 20)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:813932 发表于 2024-1-13 12:17 | 显示全部楼层
附件程序分为仿真程序和实物程序2个
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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