找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 23162|回复: 27
收起左侧

单片机6位数电子密码锁源码+PCB+仿真原理图设计(可改密码)

  [复制链接]
ID:323479 发表于 2018-5-6 15:33 | 显示全部楼层 |阅读模式
电子密码锁的电路原理图

电子密码锁的电路原理图

电子密码锁的电路原理图


Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
0.png
0.png

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


以下是一套单片机电子密码锁程序:

  1. /*******************************************************************************
  2. 初始密码:000000         密码位数:6位
  3. 注意:掉电后,所设密码会丢失,重新上电时,密码恢复为原始的000000
  4. 与P1.0相连的8位发光LED点亮代表锁被打开;熄灭代表锁被锁上

  5. 程序功能:
  6.                   1、开锁:
  7.                   下载程序后,直接按六次数字0(即代表密码000000),LED亮,锁被打开,输入密码时,
  8.                   六位数码管依次显示小横杠。
  9.                   2、更改密码:
  10.                   只有当开锁(LED亮)后,该功能方可使用。
  11.                   首先按下更改密码键,然后设置相应密码,此时六位数码管会显示设置密码对应
  12.                   的数字。最后设置完六位后,按下确认密码更改,此后新密码即生效。
  13.                   3、重试密码:
  14.                   当输入密码时,密码输错后按下重试键,可重新输入六位密码。
  15.                   当设置密码时,设置中途想更改密码,也可按下此键重新设置。
  16.                   4、关闭密码锁:
  17.                   按下上锁按键即可将打开的密码锁关闭。
  18.                   
  19. 功能测试:输入原始密码000000---按下更改密码按键---按0到9设置密码---按确认键
  20.        密码更改---按上锁按键关闭密码锁---输入新的密码打开密码锁
  21. *******************************************************************************/
  22. #include<reg52.h>

  23. #define uchar unsigned char
  24. #define uint unsigned int

  25. uchar old1,old2,old3,old4,old5,old6; //原始密码000000
  26. unsigned char PassWord[6];
  27. uchar new1,new2,new3,new4,new5,new6;  //每次MCU采集到的密码输入
  28. uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入数码管显示的变量
  29. uchar wei,key,temp;
  30. unsigned char st=0;

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


  32. sbit beep=P3^6;
  33. sbit Lock=P3^7;

  34. sbit GLED=P3^5;
  35. sbit RLED=P3^4;

  36. sbit SCL = P3^3;                  //引脚定义
  37. sbit SDA = P3^2;

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



  41. void InitI2C();
  42. void I2CStart();
  43. void I2CStop();
  44. void I2CSend(uchar byte);
  45. uchar I2CRead();
  46. uchar read_eeprom(uchar addr);
  47. void write_eeprom(uchar addr, uchar databyte);

  48. /*****************************************************************************
  49. ** 函数名称:delay
  50. ** 功能描述:延时
  51. ******************************************************************************/
  52. void delay(unsigned int i)
  53. {
  54.         uint j,k;
  55.   for(j=i;j>0;j--)
  56.     for(k=125;k>0;k--);
  57. }


  58. /*****************************************************************************
  59. ** 函数名称:InitI2C
  60. ** 功能描述:配置模拟I2C的IO端口
  61. ******************************************************************************/
  62. void InitI2C()
  63. {
  64.          SDA = 1;
  65.          SCL = 1;
  66. }

  67. /*****************************************************************************
  68. ** 函数名称:I2CStart
  69. ** 功能描述:发送I2C总线起始状态
  70. ** 输    入:无
  71. ** 输    出:无
  72. ** 全局变量:无
  73. ** 调用模块:delay()
  74. ** 可移植性:直接移植
  75. ******************************************************************************/
  76. void I2CStart()
  77. {
  78.         SDA = 1;   
  79.         delay(1);      // 延时子程序
  80.         SCL = 1;
  81.         delay(1);
  82.         SDA = 0;
  83.         delay(1);
  84.         SCL = 0;

  85. }
  86. /*****************************************************************************
  87. ** 函数名称:I2CStop
  88. ** 功能描述:发送I2C总线停止起始状态
  89. ** 输    入:无
  90. ** 输    出:无
  91. ** 全局变量:无
  92. ** 调用模块:delay()
  93. ** 可移植性:直接移植
  94. ******************************************************************************/
  95. void I2CStop()
  96. {
  97.         SCL = 0;
  98.     delay(1);
  99.         SDA = 0;
  100.         delay(1);
  101.         SCL = 1;
  102.         delay(1);
  103.         SDA = 1;
  104.         delay(1);

  105. }
  106. /*****************************************************************************
  107. ** 函数名称:I2CSend
  108. ** 功能描述:向I2C总线发送一个字节数据,并检测应答
  109. ** 输    入:待发送字节byte
  110. ** 输    出:无
  111. ** 全局变量:无
  112. ** 调用模块:delay()
  113. ** 可移植性:直接移植
  114. ******************************************************************************/
  115. void I2CSend(uchar byte)
  116. {
  117.         uchar mask;
  118.         uchar i;

  119.         mask = 0x80;
  120.         for(i = 0; i < 8; i++)
  121.         {
  122.                 SCL = 0;
  123.                 delay(1);
  124.                 if((mask & byte) == 0)
  125.                 {
  126.                         SDA = 0;
  127.                 }
  128.                 else
  129.                 {
  130.                         SDA = 1;
  131.                 }
  132.                 mask >>= 1;
  133.                 delay(1);
  134.                 SCL = 1;
  135.                 delay(1);
  136.         }
  137.         
  138.         SCL = 0;
  139.         SDA = 1;
  140.         delay(1);
  141.         SCL = 1;
  142.         delay(1);
  143.         SCL = 0;


  144.         
  145. }

  146. /*****************************************************************************
  147. ** 函数名称:I2CRead
  148. ** 功能描述:从I2C总线读取最后一个字节数据,并发送非应答位
  149. ** 输    入:无
  150. ** 输    出:接收到的字节byte
  151. ** 全局变量:无
  152. ** 调用模块:delay()
  153. ** 可移植性:直接移植
  154. ******************************************************************************/
  155. uchar I2CRead()
  156. {
  157.         uchar byte;
  158.         uchar i;

  159.         byte = 0;
  160.         for(i = 0; i < 8; i++)
  161.         {
  162.                 SCL = 0;
  163.                 SDA = 1;
  164.                 delay(1);
  165.                 SCL = 1;
  166.                 delay(1);
  167.                 byte <<= 1;         
  168.                 if(SDA == 1)
  169.                 {
  170.                         byte |= 0x01;
  171.                 }
  172.                 delay(1);
  173.         }
  174.         SCL = 0;
  175.         SDA = 1;
  176.         delay(1);
  177.         SCL = 1;
  178.         delay(1);
  179.         SCL = 0;
  180.         
  181.         return byte;

  182. }
  183. /*****************************************************************************
  184. ** 函数名称:read_eeprom
  185. ** 功能描述:读取EEPROM数据函数
  186. ** 输    入:EEPROM中目的地址addr
  187. ** 输    出:读取的数据
  188. ******************************************************************************/
  189. uchar read_eeprom(uchar addr)
  190. {
  191.         uchar databyte;

  192.         I2CStart();
  193.         I2CSend(0xa0);
  194.         I2CSend(addr);
  195.         I2CStart();
  196.         I2CSend(0xa1);
  197.         databyte = I2CRead();
  198.         I2CStop();

  199.         return databyte;
  200.         
  201. }
  202. /*****************************************************************************
  203. ** 函数名称:write_eeprom
  204. ** 功能描述:向EEPROM写入数据函数
  205. ** 输    入:EEPROM中目的地址addr及写入的数据
  206. ** 输    出:无
  207. ******************************************************************************/
  208. void write_eeprom(uchar addr, uchar databyte)
  209. {
  210.         I2CStart();
  211.         I2CSend(0xa0);            
  212.         I2CSend(addr);
  213.         I2CSend(databyte);
  214.         I2CStop();

  215. }

  216. void display(void)
  217. {
  218.         
  219.    switch(st)
  220.         {
  221.                 case 0: st=1;P0=0xff;P2=table[a];P0=0xfe;break;
  222.                 case 1: st=2;P0=0xff;P2=table[b];P0=0xfd;break;
  223.                 case 2: st=3;P0=0xff;P2=table[c];P0=0xfb;break;
  224.                 case 3: st=4;P0=0xff;P2=table[d];P0=0xf7;break;
  225.                 case 4: st=5;P0=0xff;P2=table[e];P0=0xef;break;
  226.                 case 5: st=0;P0=0xff;P2=table[f];P0=0xdf;break;
  227.         }
  228. }

  229. void Timer0() interrupt 1
  230. {
  231.         TR0=0;
  232.          TH0  = (65535-2000)/256;
  233.         TL0  = (65535-2000)%256;
  234.         display();
  235.         TR0=1;
  236. }


  237. void keyscan(void)
  238. {
  239.         P1=0xfe;
  240.    temp=P1;
  241.    temp=temp&0xf0;
  242.    if(temp!=0xf0)
  243.    {
  244.                 delay(10);
  245.       if(temp!=0xf0)
  246.       {        
  247.                         temp=P1;
  248.                         switch(temp)
  249.                         {
  250.                                 case 0xee:        key=0;wei++;break;
  251.                                 case 0xde:        key=1;wei++;break;
  252.                                 case 0xbe:        key=2;wei++;break;
  253.                                 case 0x7e:        key=3;wei++;break;
  254.          }
  255.                         beep=0;delay(50);beep=1;
  256.          while(temp!=0xf0)
  257.                         {
  258.                                 temp=P1;
  259.                                 temp=temp&0xf0;                                
  260.          }               
  261.                 }
  262.         }
  263.         P1=0xfd;
  264.         temp=P1;
  265.         temp=temp&0xf0;
  266.         if(temp!=0xf0)
  267.         {
  268.                 delay(10);
  269.                 if(temp!=0xf0)
  270.       {
  271.                         temp=P1;
  272.                         switch(temp)
  273.                         {
  274.                                 case 0xed:         key=4;wei++;break;
  275.                                 case 0xdd:        key=5;wei++;break;
  276.                                 case 0xbd:        key=6;wei++;break;
  277.                                 case 0x7d:        key=7;wei++;break;
  278.          }
  279.                         beep=0;delay(50);beep=1;
  280.          while(temp!=0xf0)
  281.          {
  282.            temp=P1;
  283.            temp=temp&0xf0;
  284.          }
  285.       }
  286.         }
  287.         P1=0xfb;
  288.         temp=P1;
  289.         temp=temp&0xf0;
  290.         if(temp!=0xf0)
  291.         {
  292.                 delay(10);
  293.       if(temp!=0xf0)
  294.       {
  295.                         temp=P1;
  296.                         switch(temp)
  297.                         {
  298.                                 case 0xeb:        key=8;wei++;break;
  299.                                 case 0xdb:        key=9;wei++;break;
  300.                                 case 0xbb:        genggai=1;wei=0;break;
  301.                                 case 0x7b:        if(allow) ok=1;break;
  302.          }
  303.                         beep=0;delay(50);beep=1;
  304.                         while(temp!=0xf0)
  305.          {
  306.                                 temp=P1;
  307.                                 temp=temp&0xf0;
  308.          }
  309.       }
  310.    }
  311.         P1=0xf7;
  312.    temp=P1;
  313.    temp=temp&0xf0;
  314.    if(temp!=0xf0)
  315.    {
  316.       delay(10);
  317.       if(temp!=0xf0)
  318.       {
  319.                         temp=P1;
  320.                         switch(temp)
  321.                         {
  322.                                 case 0xe7:        retry=1;break;
  323.                                 case 0xd7:        close=1;break;
  324.          }
  325.                         beep=0;delay(50);beep=1;
  326.                         while(temp!=0xf0)
  327.          {
  328.                                 temp=P1;
  329.                                 temp=temp&0xf0;
  330.          }
  331.       }
  332.         }
  333. }

  334. void shumima(void)                //对按键采集来的数据进行分配
  335. {
  336.         if(!wanbi)
  337.         {
  338.                 switch(wei)
  339.                 {
  340.                         case 1:        new1=key;if(!allow)a=17;else a=key;        break;
  341.                         case 2:        new2=key;if(a==17) b=17;else b=key;        break;
  342.                         case 3:        new3=key;if(a==17) c=17;else c=key;        break;
  343.                         case 4:        new4=key;if(a==17) d=17;else d=key;        break;
  344.                         case 5:        new5=key;if(a==17) e=17;else e=key;        break;
  345.                         case 6:        new6=key;if(a==17) f=17;else f=key;wanbi=1;break;
  346.                 }
  347.         }
  348. }

  349. void yanzheng(void)          //验证密码是否正确
  350. {
  351.         if(wanbi)         //只有当六位密码均输入完毕后方进行验证
  352.         {
  353.                 if((new1==PassWord[0])&(new2==PassWord[1])&(new3==PassWord[2])&(new4==PassWord[3])&(new5==PassWord[4])&(new6==PassWord[5]))
  354.                 allow=1;        //当输入的密码正确,会得到allow置一
  355.         }
  356. }


  357. void WritePassWord(void)
  358. {
  359.         unsigned char j=0;
  360.         for(j=0;j<6;j++)                        //从02地址开始写初始密码数据
  361.         {
  362.                 write_eeprom(j,PassWord[j]);         //初始密码123456
  363.                 delay(10);                                
  364.         }
  365. }

  366. void ReadPassWord(void)
  367. {
  368.         unsigned char j=0;
  369.         for(j=0;j<6;j++)                                 //将24C02中的密码读取出来保存在dumima_tab1[]数组中
  370.         {
  371.                  PassWord[j] = read_eeprom(j);
  372.                 delay(10);               
  373.         }        
  374. }

  375. void WritePassWord_Ini(void)
  376. {
  377.         unsigned char j=0;
  378.         for(j=0;j<6;j++)                        //从02地址开始写初始密码数据
  379.         {
  380.                 write_eeprom(j,j+1);         //初始密码123456
  381.                 delay(10);                                
  382.         }
  383. }

  384. void main(void)
  385. {
  386.         InitI2C();                           //初始化
  387.         TMOD = 0x01;
  388.         TH0  = (65535-2000)/256;
  389.         TL0  = (65535-2000)%256;
  390.         EA=1;
  391.         ET0=1;
  392.         TR0=1;
  393.         //WritePassWord_Ini();
  394.         ReadPassWord();
  395.         if(PassWord[0]==0xff) WritePassWord_Ini();
  396.                
  397.         while(1)
  398.         {
  399.                 keyscan();
  400.                 shumima();
  401.                 yanzheng();
  402.                 if(allow)         //验证完后,若allow为1,则开锁
  403.                 {
  404.                         Lock=0;GLED=0;RLED=1;
  405.                         if(!genggai)        wanbi=0;
  406.                 }
  407.                 else
  408.                 {
  409.                         Lock=1;GLED=1;RLED=0;
  410.                         if(wanbi)
  411.                         {
  412.                                 delay(500);
  413.                                 beep=0;delay(500);beep=1;delay(500);
  414.                                 beep=0;delay(100);beep=1;delay(200);
  415.                                 beep=0;delay(100);beep=1;delay(200);
  416.                                 beep=0;delay(100);beep=1;delay(200);
  417.                                 beep=0;delay(100);beep=1;delay(200);
  418.                                 beep=0;delay(100);beep=1;delay(200);
  419.                                 beep=0;delay(100);beep=1;
  420.                                 wei=0;wanbi=0;allow=0;
  421.                                 a=16;b=16;c=16;d=16;e=16;f=16;
  422.                                 new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
  423.                         }
  424.                         
  425.                 }
  426.                 if(genggai)          //当S16更改密码键被按下,genggai会被置一
  427.                 {
  428.                         if(allow)         //若已经把锁打开,才有更改密码的权限
  429.                         {
  430.                                 while(!wanbi)        //当新的六位密码没有设定完,则一直在这里循环
  431.                                 {
  432.                                         delay(20);
  433.                                          keyscan();
  434.                                         shumima();
  435.                                         if(retry|close)         //而当探测到重试键S18或者关闭密码锁键S19被按下时,则跳出
  436.                                         {        
  437.                                                 wanbi=1;
  438.                                                 break;
  439.                                         }
  440.                                 }
  441.                         }
  442.                 }
  443.                 if(ok)          //更改密码时,当所有六位新密码均被按下时,可以按下此键,结束密码更改
  444.                 {                  //其他时间按下此键无效
  445.                         ok=0; wei=0;Lock=1;GLED=1;RLED=0;
  446.                         genggai=0;
  447.                         PassWord[0]=new1;PassWord[1]=new2;PassWord[2]=new3; //此时,旧的密码将被代替
  448.                         PassWord[3]=new4;PassWord[4]=new5;PassWord[5]=new6;
  449.                         WritePassWord();
  450.                         wei=0;wanbi=0;allow=0;
  451.                         a=16;b=16;c=16;d=16;e=16;f=16;
  452.                         new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
  453.                 }
  454.                 if(retry)        //当重试按键S18被按下,retry会被置位
  455.                 {
  456.                         retry=0; wei=0;wanbi=0;
  457.                         a=16;b=16;c=16;d=16;e=16;f=16;
  458.                         new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;               
  459.                 }
  460.                 if(close)  //当关闭密码锁按键被按下,close会被置位
  461.                 {
  462.                         close=0;genggai=0;//所有变量均被清零。
  463.                         wei=0;        wanbi=0;
  464.                         allow=0;
  465.                         Lock=1;GLED=1;RLED=0;
  466.                         a=16;b=16;c=16;d=16;e=16;f=16;
  467.                         new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
  468.                 }
  469.         }
  470. }
复制代码

全部资料51hei下载地址:
源程序.rar (135.13 KB, 下载次数: 537)

评分

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

查看全部评分

回复

使用道具 举报

ID:118735 发表于 2018-12-27 17:44 | 显示全部楼层
楼主厉害
回复

使用道具 举报

ID:567837 发表于 2019-6-20 13:34 | 显示全部楼层
资料很好
回复

使用道具 举报

ID:282095 发表于 2019-6-20 14:01 | 显示全部楼层
密码锁可以实现远程控制吗
回复

使用道具 举报

ID:425825 发表于 2019-6-21 21:51 | 显示全部楼层
鹏博士PBs 发表于 2019-6-20 14:01
密码锁可以实现远程控制吗

需要什么样的远程?热点、局域网还是广域网的呢?
回复

使用道具 举报

ID:473471 发表于 2019-7-2 22:20 | 显示全部楼层
好资料留个脚印
回复

使用道具 举报

ID:515362 发表于 2019-7-3 18:46 | 显示全部楼层
感谢楼主无私分享
回复

使用道具 举报

ID:640942 发表于 2019-11-13 09:05 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:352449 发表于 2019-11-18 00:57 | 显示全部楼层
下载看看,学习学习。
回复

使用道具 举报

ID:644272 发表于 2019-11-19 12:37 | 显示全部楼层
楼主好厉害,好资料
回复

使用道具 举报

ID:656942 发表于 2019-12-6 15:01 来自手机 | 显示全部楼层
请问楼主有原件清单吗
回复

使用道具 举报

ID:634141 发表于 2019-12-22 16:33 | 显示全部楼层
这个真心不错,先收藏了
回复

使用道具 举报

ID:561156 发表于 2019-12-22 20:52 | 显示全部楼层
哇,这个程序刚好解决了我的一个问题
回复

使用道具 举报

ID:680994 发表于 2020-1-5 17:59 | 显示全部楼层
膜拜大佬,虚心求学
回复

使用道具 举报

ID:683564 发表于 2020-1-8 14:33 | 显示全部楼层
楼主你好这个在stc89c52中在开发板上如何连线使得电路正常工作
回复

使用道具 举报

ID:697662 发表于 2020-3-2 14:42 | 显示全部楼层
下载了为什么打不开啊
回复

使用道具 举报

ID:737227 发表于 2020-4-24 18:41 | 显示全部楼层
多谢分享
回复

使用道具 举报

ID:798056 发表于 2020-7-5 22:31 | 显示全部楼层
人机交互界面该怎么设置
回复

使用道具 举报

ID:771985 发表于 2020-8-7 17:25 | 显示全部楼层
楼主,怎么设置多个密码都能够开门
回复

使用道具 举报

ID:757431 发表于 2020-9-6 15:39 | 显示全部楼层
969355263 发表于 2020-1-8 14:33
楼主你好这个在stc89c52中在开发板上如何连线使得电路正常工作

问题加一,已经焊好了不知道怎么连上电源和烧代码进去单片机
回复

使用道具 举报

ID:825446 发表于 2020-10-6 11:04 | 显示全部楼层
有51单片机的密码锁程序吗
回复

使用道具 举报

ID:835186 发表于 2020-10-27 18:22 来自手机 | 显示全部楼层
下载完怎么看不了
回复

使用道具 举报

ID:328014 发表于 2020-10-27 18:45 | 显示全部楼层
1726739743 发表于 2020-10-27 18:22
下载完怎么看不了

我刚帮你测试了下,要用Proteus7.5版本才能打开,效果如下,输入123456,变绿灯,仿真成功
51hei.png
回复

使用道具 举报

ID:852225 发表于 2020-12-1 10:44 | 显示全部楼层
佩服楼主  
回复

使用道具 举报

ID:865382 发表于 2021-12-25 15:05 | 显示全部楼层
忘记密码怎么办啊
回复

使用道具 举报

ID:865382 发表于 2021-12-25 17:26 | 显示全部楼层
yhj1999 发表于 2020-8-7 17:25
楼主,怎么设置多个密码都能够开门

你这个问题解决了吗
回复

使用道具 举报

ID:1042648 发表于 2022-8-22 16:55 | 显示全部楼层
怎么把密码由6位数改成10位数呢?
回复

使用道具 举报

ID:1042173 发表于 2022-8-22 23:30 | 显示全部楼层
51hei团团 发表于 2020-10-27 18:45
我刚帮你测试了下,要用Proteus7.5版本才能打开,效果如下,输入123456,变绿灯,仿真成功

给我发个程序来呐,好不?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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