找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8456|回复: 9
收起左侧

基于单片机c51的六位电子密码锁仿真设计 含源码

  [复制链接]
ID:398790 发表于 2018-9-18 20:36 | 显示全部楼层 |阅读模式
电路原理图如下:
Z5J%%TBT~$_FD_XX)0Y)KCQ.png

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
0.png

密码锁按键排列操作说明
矩阵键盘按键说明

  1       2       3       确认键
  4       5       6       手动关闭锁
  7       8       9      修改密码
密码还原  0     删除键   退出键

单片机源程序如下:
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. uchar value,i;                //变量

  5. sbit relay = P2^2;  //继电器定义
  6. sbit beep  = P3^3;  //蜂鸣器定义

  7. sbit beiguan = P2^3;  //背光

  8. uint flag_time;

  9. uint flag_guan;

  10. uchar smg_i;
  11. uchar dis_smg[9]={0};

  12. uchar password[7]={8,7,6,5,4,3,2,1};            //密码保存
  13. uchar password_bj[7]={1,2,3,4,5,6,7,8};        //密码比较
  14. uchar code password_r[8] = {1,1,1,1,1,1,1,1} ;
  15. uchar code password_gl[8] = {5,2,0,0,2,5,1,1} ;
  16. uchar password_xg[8];        //密码修改
  17. uchar flag_password;      //密码正确否
  18. uchar flag_password_cichu1;//密码错误次数

  19. bit flag_200ms=1;     //200ms标志位

  20. uchar key_can;

  21. uchar menu_1,menu_i;

  22. sbit scl = P2^1;        //24C02 IO口定义
  23. sbit sda = P2^0;        //24C02 IO口定义

  24. uchar code table_num[]="0123456789abcdefg";

  25. sbit rs=P2^5;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  26. sbit rw=P2^6;         //寄存器选择信号 H:数据寄存器          L:指令寄存器
  27. sbit e =P2^7;         //片选信号   下降沿触发

  28. /***********************延时函数************************/
  29. void delay_uint(uint q)
  30. {
  31.         while(q--);
  32. }

  33. /***********************lcd1602写命令函数************************/
  34. void write_com(uchar com)
  35. {
  36.         e=0;
  37.         rs=0;
  38.         rw=0;
  39.         P0=com;
  40.         delay_uint(3);
  41.         e=1;
  42.         delay_uint(25);
  43.         e=0;
  44. }

  45. /***********************lcd1602写数据函数************************/
  46. void write_data(uchar dat)
  47. {
  48.         e=0;
  49.         rs=1;
  50.         rw=0;
  51.         P0=dat;
  52.         delay_uint(3);
  53.         e=1;
  54.         delay_uint(25);
  55.         e=0;       
  56. }

  57. /*********************光标控制***********************/
  58. void lcd1602_guanbiao(uchar open_off,uchar add)
  59. {
  60.         if(open_off == 1)   //开光标
  61.         {
  62.                 write_com(0x80+add);              //将光标移动到秒个位
  63.                 write_com(0x0f);                //显示光标并且闪烁
  64.         }
  65.         else
  66.         {
  67.                 write_com(0x0c);   //关光标
  68.         }               
  69. }

  70. /***********************lcd1602上显示两位十进制数************************/
  71. void write_sfm2(uchar hang,uchar add,uchar date)
  72. {
  73.         uchar shi,ge;
  74.         if(hang==1)   
  75.                 write_com(0x80+add);
  76.         else
  77.                 write_com(0x80+0x40+add);
  78.         shi=date%100/10;
  79.         ge=date%10;                  
  80.         write_data(0x30+shi);
  81.         write_data(0x30+ge);       
  82. }

  83. /***********************lcd1602上显示这字符函数************************/
  84. void write_string(uchar hang,uchar add,uchar *p)
  85. {
  86.         if(hang==1)   
  87.                 write_com(0x80+add);
  88.         else
  89.                 write_com(0x80+0x40+add);
  90.                 while(1)                                                                                                                 
  91.                 {
  92.                         if(*p == '\0')  break;
  93.                         write_data(*p);
  94.                         p++;
  95.                         delay_uint(50);
  96.                 }       
  97. }


  98. /***********************lcd1602初始化设置************************/
  99. void init_1602()
  100. {
  101.         write_com(0x38);        //
  102.         write_com(0x0c);
  103.         write_com(0x06);
  104.         delay_uint(1000);
  105.         write_string(1,0," Password Lock  ");       
  106.         write_string(2,0," Input:         ");
  107.         lcd1602_guanbiao(1,7+0x40);  //开光标
  108. }


  109. /***************启始信号 ***************************/
  110. void start()
  111. {
  112.         sda = 1;
  113.         scl = 1;
  114.         sda = 0;
  115.         scl = 0;
  116. }

  117. /****************结束信号 **************************/
  118. void stop()
  119. {
  120.         sda = 0;
  121.         scl = 1;
  122.         sda = 1;
  123.         scl = 0;
  124. }

  125. /*****************检测应答*************************/
  126. void ack()
  127. {
  128.         uchar i;
  129.         sda = 1;   
  130.         scl = 1;       
  131.         while((i < 100) & (sda == 1))        i++;
  132.         scl =0;
  133. }


  134. void ack_zhuji()
  135. {
  136.         sda = 0;
  137.         scl = 1;
  138.         scl = 0;
  139.         sda = 1;
  140. }

  141. /*****************非应答*************************/
  142. void no_ack()
  143. {
  144.         sda = 1;
  145.         scl = 1;
  146.         scl = 0;
  147. }

  148. /*****************写一个字节*************************/
  149. void write_iic(uchar dat)
  150. {
  151.         uchar i;
  152.         for(i=0;i<8;i++)
  153.         {
  154.                 scl = 0;
  155.                 dat <<= 1 ;
  156.                 sda = CY;
  157.                 scl = 1;
  158.         }
  159.         scl = 0;
  160. }

  161. /*******************读一个字节***********************/
  162. uchar read_iic()
  163. {
  164.         uchar i,value;
  165.         for(i=0;i<8;i++)
  166.         {
  167.                 scl = 1;
  168.                 value <<= 1;
  169.                 if(sda == 1)
  170.                         value |= 0x01;
  171.                 scl = 0;
  172.         }
  173.         return value;
  174. }

  175. /*****************向24C02写一个字节进去*************************/
  176. void write_24c02(uchar add,uchar dat)
  177. {
  178.         start();
  179.         write_iic(0xa0);
  180.         ack();
  181.         write_iic(add);
  182.         ack();
  183.         write_iic(dat);
  184.         no_ack();
  185.         stop();
  186. }

  187. /******************从24C02读一个字节进去************************/
  188. uchar read_24c02(uchar add)
  189. {
  190.         uchar value;
  191.         start();
  192.         write_iic(0xa0);
  193.         ack();
  194.         write_iic(add);
  195.         ack();

  196.         start();
  197.         write_iic(0xa1);
  198.         ack();
  199.         value = read_iic();
  200.         no_ack();
  201.         stop();
  202.         return value;
  203. }

  204. /*****************向24C02写多个字节进去*************************/
  205. void write_24c02_8(uchar n,uchar add,uchar *p)
  206. {
  207.         uchar i;
  208.         EA = 0;
  209.         start();
  210.         write_iic(0xa0);
  211.         ack();
  212.         write_iic(add);       
  213.         for(i=0;i<n;i++)
  214.         {       
  215.                 ack();
  216.                 write_iic(*p);
  217.                 p++;                       
  218.         }  
  219.         no_ack();   
  220.         stop();       
  221.         EA = 1;
  222. }
  223. /******************从24C02读多个字节进去************************/
  224. void read_24c02_8(uchar n,uchar add,uchar *p)
  225. {
  226.         uchar i;
  227.         EA = 0;
  228.         start();
  229.         write_iic(0xa0);
  230.         ack();
  231.         write_iic(add);
  232.         ack();

  233.         start();
  234.         write_iic(0xa1);
  235.         ack();
  236.         for(i=0;i<n;i++)
  237.         {
  238.                 p[i] = read_iic();
  239.                 if(i == n-1)
  240.                 {
  241.                         ack();
  242.                         stop();
  243.                 }
  244.                 else
  245.                         ack_zhuji();
  246.         }
  247.         EA = 1;
  248. }


  249. /***********************1ms延时函数*****************************/
  250. void delay_1ms(uint q)
  251. {
  252.         uint i,j;
  253.         for(i=0;i<q;i++)
  254.                 for(j=0;j<120;j++);
  255. }


  256. void key()         //独立按键程序
  257. {
  258.         static uchar key_new = 0, key_l;
  259.         key_can = 20;                   //按键值还原
  260.         P1 = 0x0f;
  261.         if((P1 & 0x0f) != 0x0f)                //按键按下
  262.         {
  263.                 delay_1ms(1);                     //按键消抖动
  264.                 if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
  265.                 {                                                //确认是按键按下
  266.                         key_new = 0;
  267.                         key_l = (P1 | 0xf0);   //矩阵键盘扫描
  268.                         P1 = key_l;
  269.                         switch(P1)
  270.                         {
  271.                                 case 0xee:  key_can = 1;  break;  //得到按键值
  272.                                 case 0xde:  key_can = 4;  break;   //得到按键值
  273.                                 case 0xbe:  key_can = 7;  break;   //得到按键值
  274.                                 case 0x7e:  key_can = 10;  break;   //得到按键值
  275.        
  276.                                 case 0xed:  key_can = 0;  break;  //得到按键值
  277.                                 case 0xdd:  key_can = 8;  break;   //得到按键值
  278.                                 case 0xbd:  key_can = 5;  break;   //得到按键值
  279.                                 case 0x7d:  key_can = 2;  break;   //得到按键值
  280.        
  281.                                 case 0xeb:  key_can = 3;  break;  //得到按键值
  282.                                 case 0xdb:  key_can = 6;  break;   //得到按键值
  283.                                 case 0xbb:  key_can = 9;  break;   //得到按键值
  284.                                 case 0x7b:  key_can = 11;  break;   //得到按键值
  285.        
  286.                                 case 0xe7:  key_can = 15;  break;  //得到按键值
  287.                                 case 0xd7:  key_can = 14;  break;  //得到按键值
  288.                                 case 0xb7:  key_can = 13;  break;   //得到按键值
  289.                                 case 0x77:  key_can = 12;  break;  //得到按键值  

  290.                         }       
  291.                 }                       
  292.         }
  293.         else
  294.         {
  295.                 key_new = 1;
  296.         }       
  297. }


  298. /***************把数组清空**********************/
  299. void clear_shuzu(uchar *p)
  300. {
  301.         for(i=0;i<9;i++)
  302.                 p[i] = 0;
  303. }

  304. /*************定时器0初始化程序***************/
  305. void time_init()          
  306. {
  307.         EA   = 1;                   //开总中断
  308.         TMOD = 0X01;          //定时器0、工作方式1
  309.         ET0  = 1;                  //开定时器0中断
  310.         TR0  = 1;                  //允许定时器0定时
  311. }

  312. /******************下载程序密码初始化**********************/          
  313. void password_chushifa()
  314. {
  315.         scl = 0;
  316.         value = read_24c02(10) ;
  317.         if(value != 75)
  318.         {
  319.                 value = 75;
  320.                 beep = 0;
  321.                 write_24c02(10,value);
  322.                 delay_1ms(200);
  323.                 write_24c02_8(8,0,password_r);
  324.                 delay_1ms(200);
  325.                 read_24c02_8(8,0,password);
  326.                 beep = 1;          
  327.         }
  328. }


  329. /****************按键功能处理********************/          
  330. void key_with()
  331. {
  332.         static uchar value;
  333.         if(key_can == 14)   //手动关闭密码锁
  334.                 relay = 1;
  335.         if(menu_1 == 0)
  336.         {
  337.                 if(key_can <= 9)
  338.                 if(menu_i < 8)   //密码输入
  339.                 {
  340.                         menu_i ++;
  341.                         if(menu_i > 8)
  342.                                 menu_i = 8;
  343.                         smg_i = menu_i;
  344.                         for(i=8;i>0;i--)
  345.                                 password_bj[i] = password_bj[i-1];       
  346.                         password_bj[0] = key_can;
  347.                         for(i=0;i<smg_i;i++)
  348.                                 dis_smg[i] ='*';//0x40 + password_bj[i];
  349.                         write_string(2,7,dis_smg);       
  350.                         lcd1602_guanbiao(1,7 + menu_i + 0x50);  //开光标
  351.                 }       
  352.                 if(key_can == 11)         //密码删除
  353.                 {
  354.                         for(i=0;i<menu_i;i++)
  355.                                 password_bj[i] = password_bj[i+1];          
  356.                         menu_i --;
  357.                         password_bj[menu_i] = ' ';       
  358.                         dis_smg[menu_i] = ' ';
  359.                         write_string(2,7,dis_smg);       
  360.                         lcd1602_guanbiao(1,7 + menu_i + 0x50);  //开光标
  361.                 }
  362.                 if(key_can == 15)  //确认键
  363.                 {
  364.                         value = 0;
  365.                         for(i=0;i<8;i++)
  366.                         {
  367.                                 if(password_bj[i] == password_gl[i]) //判断管理员密码
  368.                                 {
  369.                                          value ++;
  370.                                         if(value >= 8)  //密码正确
  371.                                         {
  372.                                                 write_string(2,0,"    return      ");
  373.                                                 beep = 0;
  374.                                                 delay_1ms(200);
  375.                                                 read_24c02_8(8,0,password);
  376.                                                 beep = 1;          
  377.                                                 delay_1ms(2000);
  378.                                         }
  379.                                 }
  380.                         }
  381.                         if(value < 8)
  382.                         for(i=0;i<8;i++)
  383.                         {
  384.                                 if(password_bj[i] == password[i])
  385.                                 {
  386.                                         flag_password = 1;         //密码正确
  387.                                         relay = 0;     //打开密码锁
  388.                                         for(i=0;i<8;i++)
  389.                                                 dis_smg[i] = 0xbf;
  390.                                 }
  391.                                 else
  392.                                 {
  393.                                         flag_password = 0;
  394.                                         flag_password_cichu1 ++;
  395.                                         write_string(1,0," Password error ");       
  396.                                         write_string(2,0,"   cishu:       ");
  397.                                         write_sfm2(2,9,flag_password_cichu1);
  398.                                         delay_1ms(280);
  399.                        
  400.                                         for(i=0;i<8;i++)
  401.                                         {
  402.                                                 beep = ~beep;
  403.                                                 delay_1ms(200);
  404.                                         }
  405.                                         beep = 1;
  406.                                         delay_1ms(800);
  407.                                         break;               //密码不正确
  408.                                 }
  409.                         }
  410.                         clear_shuzu(dis_smg);
  411.                         write_string(1,0," Password Lock  ");       
  412.                         write_string(2,0," Input:         ");
  413.                         lcd1602_guanbiao(1,7+0x50);  //开光标
  414.                         menu_i = 0;
  415.                 }
  416.         }                                                                       
  417. }

  418. /****************修改密码********************/          
  419. void xiugai_password()
  420. {
  421.         if(key_can == 13)   //修改密码
  422.         {
  423.                 if((relay == 0) && (menu_1 == 0))
  424.                 {
  425.                         menu_1 = 1;        menu_i = 0;
  426.                         clear_shuzu(password_bj);          //数据清空
  427.                         clear_shuzu(dis_smg);
  428.                         write_string(1,0,"Input1:          ");       
  429.                         write_string(2,0,"Input2:          ");
  430.                         lcd1602_guanbiao(1,7);  //开光标
  431.                 }       
  432.         }
  433.         if(menu_1 == 1)   //第一次输入修改的密码
  434.         {
  435.                 if(key_can <= 9)
  436.                 {
  437.                         if(menu_i < 8)
  438.                         {
  439.                                 menu_i ++;
  440.                                 if(menu_i > 8)
  441.                                         menu_i = 8;
  442.                                 smg_i = menu_i;
  443.                                 for(i=9;i>0;i--)
  444.                                         password_bj[i] = password_bj[i-1];       
  445.                                 password_bj[0] = key_can;
  446.                                 for(i=0;i<menu_i;i++)
  447.                                         dis_smg[i] ='*';
  448.                                 write_string(1,9,dis_smg);
  449.                                 lcd1602_guanbiao(1,9 + menu_i);  //开光标       
  450.                         }       
  451.                 }
  452.                 if(key_can == 11)  //删除键
  453.                 {
  454.                         for(i=0;i<menu_i;i++)
  455.                                 password_bj[i] = password_bj[i+1];       
  456.                         menu_i --;
  457.                         password_bj[menu_i] = ' ';       
  458.                         dis_smg[menu_i] = ' ';
  459.                         write_string(1,9,dis_smg);       
  460.                         lcd1602_guanbiao(1,9 + menu_i);  //开光标       
  461.                 }       
  462.                 if(key_can == 15)  //确定键
  463.                 {
  464.                         clear_shuzu(password_xg);
  465.                         clear_shuzu(dis_smg);
  466.                         lcd1602_guanbiao(1,8 + 0x50);  //开光标
  467.                         menu_1 = 2;
  468.                     menu_i = 0;
  469.                         key_can = 20;
  470.                 }
  471.         }
  472.         if(menu_1 == 2)   //第二次输入修改的密码
  473.         {
  474.                 if(key_can <= 9)
  475.                 {
  476.                         if(menu_i < 8)
  477.                         {
  478.                                 menu_i ++;               
  479.                                 if(menu_i > 8)
  480.                                         menu_i = 8;
  481.                                 for(i=7;i>0;i--)
  482.                                         password_xg[i] = password_xg[i-1];       
  483.                                 password_xg[0] = key_can;
  484.                                 for(i=0;i<menu_i;i++)
  485.                                         dis_smg[i] ='*';//0x40 + password_xg[i];
  486.                                 write_string(2,7,dis_smg);          
  487.                                 lcd1602_guanbiao(1,7 + menu_i + 0x50);  //开光标
  488.                         }       
  489.                 }
  490.                 if(key_can == 11)  //删除键
  491.                 {
  492.                         for(i=0;i<menu_i;i++)
  493.                                 password_xg[i] = password_xg[i+1];       
  494.                         password_xg[menu_i] = ' ';       
  495.                         dis_smg[menu_i] = ' ';
  496.                         write_string(2,7,dis_smg);       
  497.                         lcd1602_guanbiao(1,7 + menu_i + 0x50);  //开光标
  498.                 }       
  499.                 if(key_can == 15)  //确定键
  500.                 {
  501.                         for(i=0;i<8;i++)
  502.                         {
  503.                                 if(password_bj[i] == password_xg[i])
  504.                                 {
  505.                                         flag_password = 1;         //两次输入的密码一样                       
  506.                                 }
  507.                                 else
  508.                                 {
  509.                                         flag_password = 0;
  510.                                         write_string(1,0," Password Error ");       
  511.                                         write_string(2,0,"     reenter    ");
  512.                                         delay_1ms(300);
  513.                                         for(i=0;i<8;i++)
  514.                                         {
  515.                                                 beep = ~beep;                //提示三声
  516.                                                 delay_1ms(300);
  517.                                         }
  518.                                         beep = 1;
  519.                                         delay_1ms(1000);
  520.                                         break;               //密码不正确
  521.                                 }
  522.                         }
  523.                         if(flag_password == 1)                 //两次输入的密码一样的
  524.                         {                       
  525.                                 for(i=0;i<8;i++)
  526.                                 {
  527.                                         write_string(1,0,"    Password    ");       
  528.                                         write_string(2,0,"    Succeed     ");
  529.                                         password[i] = password_bj[i];   //保存密码
  530.                                 }
  531.                                 write_24c02_8(8,0,password);
  532.                                 delay_1ms(300);
  533.                                 beep = 0;
  534.                                 delay_1ms(2000);
  535.                                 beep = 1;
  536.                         }
  537.                         clear_shuzu(password_xg);
  538.                         clear_shuzu(dis_smg);
  539.                         write_string(1,0," Password Lock  ");       
  540.                         write_string(2,0," Input:         ");
  541.                         lcd1602_guanbiao(1,7+0x50);  //开光标
  542.                         menu_1 = 0;
  543.                     menu_i = 0;

  544.                 }
  545.         }       
  546. }


  547. /******************主程序**********************/          
  548. void main()
  549. {
  550.         static uint value ;
  551.         password_chushifa();
  552.         time_init();   //定时器初始化
  553.         read_24c02_8(8,0,password);
  554.         init_1602();
  555.         beiguan = 0;
  556.         while(1)
  557. ……………………

  558. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
dianzimimasuo.zip (834.88 KB, 下载次数: 168)
回复

使用道具 举报

ID:89286 发表于 2018-9-19 18:59 | 显示全部楼层
thanks for sharing 源码是c格式的 需要自己建立工程
回复

使用道具 举报

ID:112693 发表于 2018-10-2 00:31 | 显示全部楼层
大哥,初始密码是多少?
回复

使用道具 举报

ID:407585 发表于 2018-10-11 15:55 | 显示全部楼层
初始密码是啥
回复

使用道具 举报

ID:408691 发表于 2018-10-12 21:52 | 显示全部楼层
元件都用的啥
回复

使用道具 举报

ID:488642 发表于 2019-3-15 16:21 | 显示全部楼层
这个密码锁的密码是多少啊??
回复

使用道具 举报

ID:681840 发表于 2020-1-6 00:38 来自手机 | 显示全部楼层
这是数码管显示还是液晶屏显示?
回复

使用道具 举报

ID:186710 发表于 2020-3-27 18:02 | 显示全部楼层
仿真电路没法输入密码,怎么回事?
回复

使用道具 举报

ID:163002 发表于 2020-4-6 15:28 | 显示全部楼层
初始密码多少
回复

使用道具 举报

ID:435715 发表于 2020-4-12 13:51 | 显示全部楼层
程序被你自己改废了,下次不要乱改了嗷。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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