找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2449|回复: 0
收起左侧

单片机密码锁源代码(掉电可记忆密码)

[复制链接]
ID:260372 发表于 2017-12-12 11:43 | 显示全部楼层 |阅读模式
仿真原理图:http://www.51hei.com/bbs/dpj-101350-1.html
单片机源程序如下:
  1. /********************************************************************************
  2.                                                                 功能键
  3.                                                 S6---S115        数字键0-9
  4.                                 S16---更改密码                S17---更改密码完毕后确认
  5.                                 S18---重试密码、重新设定        S19---关闭密码锁
  6.                                 初始密码:000000         密码位数:6位
  7.                                 注意:掉电后,所设密码会丢失,重新上点时,密码恢复为原始的000000
  8.                                 与P1相连的8位发光LED点亮代表锁被打开;熄灭代表锁被锁上

  9. 程序功能:
  10.                   1、开锁:
  11.                   下载程序后,直接按六次S6(即代表数字0),8位LED亮,锁被打开,输入密码时,
  12.                   六位数码管依次显示小横杠。
  13.                   2、更改密码:
  14.                   只有当开锁(LED亮)后,该功能方可使用。
  15.                   首先按下更改密码键S16,然后设置相应密码,此时六位数码管会显示设置密码对应
  16.                   的数字。最后设置完六位后,按下S17确认密码更改,此后新密码即生效。
  17.                   3、重试密码:
  18.                   当输入密码时,密码输错后按下键S18,可重新输入六位密码。
  19.                   当设置密码时,设置中途想更改密码,也可按下此键重新设置。
  20.                   4、关闭密码锁:
  21.                   按下S19即可将打开的密码锁关闭。
  22. 推荐初级演示步骤:输入原始密码000000按6次S6密码正确后LED全部亮表示锁已打开---按下更
  23. 改密码按键S16---按S6到S15设置密码---按S17
  24.                         确认密码更改---按S19关闭密码锁---输入新的密码打开密码锁
  25. *******************************************************************************/
  26. #include<reg52.h>
  27. #include <intrins.h>
  28. #define uint unsigned int
  29. #define uchar unsigned char

  30. uchar old1,old2,old3,old4,old5,old6; //原始密码000000
  31. uchar new1,new2,new3,new4,new5,new6;  //每次MCU采集到的密码输入
  32. uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入数码管显示的变量
  33. uchar wei,key,temp;

  34. bit allow,genggai,ok,wanbi,retry,close;         //各个状态位

  35. sbit dula=P2^6;
  36. sbit wela=P2^7;
  37. sbit beep=P2^3;
  38. sbit sda=P2^0;                          //IO口定义
  39. sbit scl=P2^1;

  40. unsigned char code table[]=
  41. {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
  42. 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};

  43. /*****************IIC芯片24C02存储器驱动程序************************************/

  44. void nop()
  45. {
  46.         _nop_();
  47.         _nop_();
  48. }
  49. /////////24C02读写驱动程序////////////////////
  50. void delay1(unsigned int m)
  51. {        unsigned int n;
  52.           for(n=0;n<m;n++);
  53. }

  54. void init()  //24c02初始化子程序
  55. {
  56.         scl=1;
  57.         nop();
  58.         sda=1;
  59.         nop();
  60. }

  61. void start()        //启动I2C总线
  62. {
  63.         sda=1;
  64.         nop();
  65.         scl=1;
  66.         nop();
  67.         sda=0;
  68.         nop();
  69.         scl=0;
  70.         nop();
  71. }

  72. void stop()         //停止I2C总线
  73. {
  74.         sda=0;
  75.         nop();
  76.         scl=1;
  77.         nop();
  78.         sda=1;
  79.         nop();
  80. }

  81. void writebyte(unsigned char j)  //写一个字节
  82. {
  83.         unsigned char i,temp;
  84.            temp=j;
  85.            for (i=0;i<8;i++)
  86.    {
  87.            temp=temp<<1;
  88.            scl=0;
  89.            nop();
  90.            sda=CY;                //temp左移时,移出的值放入了CY中
  91.            nop();
  92.            scl=1;                //待sda线上的数据稳定后,将scl拉高
  93.            nop();
  94.    }
  95.    scl=0;
  96.    nop();
  97.    sda=1;
  98.    nop();
  99. }

  100. unsigned char readbyte()   //读一个字节
  101. {
  102.    unsigned char i,j,k=0;
  103.    scl=0; nop(); sda=1;
  104.    for (i=0;i<8;i++)
  105.    {  
  106.                 nop(); scl=1; nop();
  107.               if(sda==1)
  108.                 j=1;
  109.               else
  110.                 j=0;
  111.               k=(k<<1)|j;
  112.                   scl=0;
  113.         }
  114.            nop();
  115.         return(k);
  116. }

  117. void clock()         //I2C总线时钟
  118. {
  119.    unsigned char i=0;
  120.    scl=1;
  121.    nop();
  122.    while((sda==1)&&(i<255))
  123.              i++;
  124.    scl=0;
  125.    nop();
  126. }

  127. ////////从24c02的地址address中读取一个字节数据/////
  128. unsigned char read24c02(unsigned char address)
  129. {
  130.    unsigned char i;
  131.    start();
  132.    writebyte(0xa0);
  133.    clock();
  134.    writebyte(address);
  135.    clock();
  136.    start();
  137.    writebyte(0xa1);
  138.    clock();
  139.    i=readbyte();
  140.    stop();
  141.    delay1(100);
  142.    return(i);
  143. }

  144. //////向24c02的address地址中写入一字节数据info/////
  145. void write24c02(unsigned char address,unsigned char info)
  146. {
  147.    start();
  148.    writebyte(0xa0);
  149.    clock();
  150.    writebyte(address);
  151.    clock();
  152.    writebyte(info);
  153.    clock();
  154.    stop();
  155.    delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。
  156. }
  157. /****************************密码锁程序模块********************************************************/

  158. void delay(unsigned char i)
  159. {
  160.         uchar j,k;
  161.   for(j=i;j>0;j--)
  162.     for(k=125;k>0;k--);
  163. }

  164. void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
  165. {
  166.    dula=0;
  167.    P0=table[a];
  168.    dula=1;
  169.    dula=0;
  170.    
  171.    wela=0;
  172.    P0=0xfe;
  173.    wela=1;
  174.    wela=0;
  175.    delay(5);
  176.    
  177.    P0=table[b];
  178.    dula=1;
  179.    dula=0;
  180.    
  181.    P0=0xfd;
  182.    wela=1;
  183.    wela=0;
  184.    delay(5);

  185.    P0=table[c];
  186.    dula=1;
  187.    dula=0;
  188.    
  189.    P0=0xfb;
  190.    wela=1;
  191.    wela=0;
  192.    delay(5);
  193.    
  194.    P0=table[d];
  195.    dula=1;
  196.    dula=0;
  197.    
  198.    P0=0xf7;
  199.    wela=1;
  200.    wela=0;
  201.    delay(5);
  202.    
  203.    P0=table[e];
  204.    dula=1;
  205.    dula=0;
  206.    
  207.    P0=0xef;
  208.    wela=1;
  209.    wela=0;
  210.    delay(5);
  211.    
  212.    P0=table[f];
  213.    dula=1;
  214.    dula=0;
  215.    
  216.    P0=0xdf;
  217.    wela=1;
  218.    wela=0;
  219.    delay(5);
  220. }


  221. void keyscan()
  222. {
  223.   {        
  224.     P3=0xfe;
  225.     temp=P3;
  226.     temp=temp&0xf0;
  227.     if(temp!=0xf0)
  228.     {
  229.       delay(10);
  230.       if(temp!=0xf0)
  231.       {        
  232.         temp=P3;
  233.         switch(temp)
  234.         {
  235.           case 0xee:
  236.                key=0;
  237.                            wei++;
  238.                break;

  239.           case 0xde:
  240.                key=1;
  241.                            wei++;
  242.                break;

  243.           case 0xbe:
  244.                key=2;
  245.                            wei++;
  246.                break;

  247.           case 0x7e:
  248.                key=3;
  249.                            wei++;
  250.                break;
  251.          }
  252.          while(temp!=0xf0)
  253.         {
  254.            temp=P3;
  255.            temp=temp&0xf0;
  256.            beep=0;
  257.          }
  258.          beep=1;
  259.       }
  260.     }
  261.     P3=0xfd;
  262.     temp=P3;
  263.     temp=temp&0xf0;
  264.     if(temp!=0xf0)
  265.     {
  266.       delay(10);
  267.       if(temp!=0xf0)
  268.       {
  269.         temp=P3;
  270.         switch(temp)
  271.         {
  272.           case 0xed:
  273.                key=4;
  274.                            wei++;
  275.                break;

  276.           case 0xdd:
  277.                key=5;
  278.                            wei++;
  279.                break;

  280.           case 0xbd:
  281.                key=6;
  282.                            wei++;
  283.                break;

  284.           case 0x7d:
  285.                key=7;
  286.                            wei++;
  287.                break;
  288.          }
  289.          while(temp!=0xf0)
  290.          {
  291.            temp=P3;
  292.            temp=temp&0xf0;
  293.            beep=0;
  294.          }
  295.          beep=1;
  296.       }
  297.       }
  298.     P3=0xfb;
  299.     temp=P3;
  300.     temp=temp&0xf0;
  301.     if(temp!=0xf0)
  302.     {
  303.       delay(10);
  304.       if(temp!=0xf0)
  305.       {
  306.         temp=P3;
  307.         switch(temp)
  308.         {
  309.           case 0xeb:
  310.                key=8;
  311.                            wei++;
  312.                break;

  313.           case 0xdb:
  314.                key=9;
  315.                            wei++;
  316.                break;
  317.                            
  318.           case 0xbb:
  319.                genggai=1;
  320.                            wei=0;
  321.                break;

  322.           case 0x7b:
  323.                              if(allow)
  324.                ok=1;
  325.                break;
  326.          }
  327.         while(temp!=0xf0)
  328.          {
  329.            temp=P3;
  330.            temp=temp&0xf0;
  331.            beep=0;
  332.          }
  333.          beep=1;
  334.       }
  335.       }
  336.           P3=0xf7;
  337.     temp=P3;
  338.     temp=temp&0xf0;
  339.     if(temp!=0xf0)
  340.     {
  341.       delay(10);
  342.       if(temp!=0xf0)
  343.       {
  344.         temp=P3;
  345.         switch(temp)
  346.         {
  347.           case 0xe7:
  348.                              retry=1;
  349.                break;

  350.           case 0xd7:
  351.                              close=1;
  352.                break;
  353.          }
  354.         while(temp!=0xf0)
  355.          {
  356.            temp=P3;
  357.            temp=temp&0xf0;
  358.            beep=0;
  359.          }
  360.          beep=1;
  361.       }
  362.       }
  363. }
  364. }

  365. void shumima()                //对按键采集来的数据进行分配
  366. {
  367.         if(!wanbi)
  368.         {
  369.         switch(wei)
  370.         {
  371.                 case 1:new1=key;
  372.                             if(!allow)        a=17;
  373.                            else a=key;        break;
  374.                 case 2:new2=key;
  375.                                 if(a==17) b=17;
  376.                                 else b=key;        break;
  377.                 case 3:new3=key;
  378.                                 if(a==17) c=17;
  379.                                 else c=key;        break;
  380.                 case 4:new4=key;
  381.                                 if(a==17) d=17;
  382.                                 else d=key;        break;
  383.                 case 5:new5=key;
  384.                                 if(a==17) e=17;
  385.                                 else e=key;        break;
  386.                 case 6:new6=key;
  387.                                 if(a==17) f=17;
  388.                                 else f=key;
  389.                                 wanbi=1;        break;
  390.         }
  391.         }
  392. }

  393. void yanzheng()          //验证密码是否正确
  394. {
  395.         if(wanbi)         //只有当六位密码均输入完毕后方进行验证
  396.         {
  397.         if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
  398.                 allow=1;        //当输入的密码正确,会得到allowe置一
  399.         }
  400. }

  401. void main()
  402. {
  403.         
  404.         init();        //初始化24C02
  405. /*********下面的一小段程序的功能为格式化密码存储区。************
  406. ******当24c02中这些存储区由于其他程序的运行而导致***************
  407. *******所存数据发生了变化,或者密码遗忘时,        ********************
  408. ******可以删掉其前面的注释线,然后重新编译下载。****************
  409. ******而将密码还原为000000后,请将下面的程序用******************
  410. ******注释屏蔽掉,重新编译、下载,方可正常使用****************/
  411. //        write24c02(110,0x00);
  412. //        write24c02(111,0x00);//24c02的第110到115地址单元作为密码存储区
  413. //        write24c02(112,0x00);
  414. //        write24c02(113,0x00);
  415. //        write24c02(114,0x00);
  416. //        write24c02(115,0x00);
  417. /*******************************************************************/


  418.         old1=read24c02(110);  
  419.         old2=read24c02(111);
  420.         old3=read24c02(112);
  421.         old4=read24c02(113);
  422.         old5=read24c02(114);
  423.         old6=read24c02(115);

  424.         while(1)
  425.         {
  426.                 keyscan();
  427.                 shumima();
  428.                 yanzheng();
  429. ……………………

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

所有资料51hei提供下载:
密码锁(掉电可记忆密码).rar (36.07 KB, 下载次数: 25)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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