找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4720|回复: 2
收起左侧

基于stc15单片机的4位电子密码锁设计分享 代码+PCB+实物

[复制链接]
ID:128314 发表于 2019-3-5 23:41 | 显示全部楼层 |阅读模式
这是我上学期学校实训做的电子密码锁,主控芯片选择的是stc15f2k60s2,4位数码管作为显示模块,设置密码存放在单片机内部的eeprom中。附件中包含4位电子密码锁的原理图和PCB设计以及源代码,分享给大家,希望大家一起进步。

密码锁的详细的操作说明如下:
1、密码锁初始密码是2019,密码修改成功后一定要记住自己设置密码,否则下次不能正常
   开锁。
2、初始上电情况下,密码锁处于关闭状态,数码管显示"OFF"。此时短按按键S3进入输入
   密码状态。通过按键完成4位密码的输入,s1按键代表加,s2按键代表减,s3按键代表移
   位(通过s3按键完成不同密码位的切换输入),当四位密码输入完成后,长按s3按键,系统
   进行输入密码和实际密码的校验
3、输入密码正确,密码锁进入开锁状态,数码管显示"OPEN"。此时短按按键s1(正常按下),
   密码锁进入关闭状态,数码管显示"OFF"。输入密码错误,数码管上闪烁'----'4次,然后显
   示OFF想要再次开锁还需重复2的操作。
4、密码锁只有处于开锁状态情况下才能设置新的密码。密码锁处于开锁状态下,长按(一直按
   住按键,直到数码管提示密码输入)S2按键进入设置新密码状态。新密码输入完成后,长按
   S3键,密码保存到EEPROM中。如果新密码设置成功,数码管上会闪烁"666"4次,然后显示
   OPEN;如果新密码设置失败,数码管会闪烁 "FFFF"4次,然后显示OPEN。设置新密码失败如
   果重新设置密码锁,重复步骤3操作。

实物图

密码锁关闭

密码锁关闭


输入密码

输入密码


密码锁打开

密码锁打开


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

+-------------------------------------------------------------------+
*        +    由于按键资源有限,某些按键必须支持复用功能,长按、短按操作一   +     
*        +    定要注意                                                       +
            +              S1按键---------------->P0.5端口                      +
*        +              S2按键---------------->P0.6端口                      +
*        +              S3按键---------------->P0.7端口                      +
*        +                                                                   +
*        +     本代码完全按照实验提供原理图编写,如果你在设置硬件时更改原理  +
*        +     图(可能是因为提供原理图 单层布线完全),你需要根据自己原理图 +
*        +     更改数码管位选和段选(bsp_smg.c文件)                           +
*        +-------------------------------------------------------------------+  

单片机程序代码如下:
  1. /*
  2. *********************************************************************************************************
  3. *
  4. *        模块名称 : 电子密码锁核心模块。
  5. *        文件名称 : code_lock.c
  6. *        版    本 : V1.0
  7. *        说    明 : 电子密码锁
  8. *
  9. *
  10. *********************************************************************************************************
  11. */
  12. #include "bsp.h"
  13. #include "code_lock.h"

  14. #define SUCCESS               1
  15. #define FALSE                 0

  16. #define CALIBRATION           0x80

  17. /* 第一个扇区EEPROM的起始地址 */
  18. #define PASSWORD_SAVE_ADDR    0x00                /* 密码存放在单片机EEPROM中初始地址 */
  19. /* 第二个扇区EEPROM的起始地址 */
  20. #define PASSWORD_IS_MODIFY    0x300               /* 读取此地址内容,判断默认密码是否被
  21.                                                      修改,如果被修改每次上电后必须从密
  22.                                                                                                                                           码存放地址处读取密码,并将其存放到结
  23.                                                                                                                                           构体成员变量password数组中 */

  24.                                                                                                                                                      
  25. LOCK_T s_tLock;

  26. static void WiatUnlock(LOCK_T * p_Lock);
  27. static void AreUnlock(LOCK_T * p_Lock);
  28. static void HaveUnlock(LOCK_T * p_Lock);
  29. static void SetPassword(LOCK_T * p_Lock);
  30. static uint8_t CheckWriteStatus(LOCK_T * p_Lock);

  31. /*
  32. *********************************************************************************************************
  33. *        函 数 名: Init_Lock_Var
  34. *        功能说明: 初始化密码锁初始密码
  35. *        形    参: 无
  36. *        返 回 值: 无
  37. *********************************************************************************************************
  38. */
  39. void Init_Lock(void)
  40. {
  41.         uint8_t tmp;
  42.         uint8_t pBuffer[PASSWORD_MAX_BIT] = {2, 0, 1, 9};
  43.         uint8_t n;
  44.         
  45.         for(n = 0; n < 4; n++)
  46.                 s_tLock.Password[n] = pBuffer[n];
  47.         
  48.         /* 读取PASSWORD_IS_MODIFY地址内容,判断默认密码是否被修改 */
  49.         EEPROM_read_n(PASSWORD_IS_MODIFY,&tmp,1);
  50.         /* 默认密码已经被修改,从eeprom中读入密码到password数组 */
  51.         if(tmp == CALIBRATION)
  52.         {
  53.                 EEPROM_read_n(PASSWORD_SAVE_ADDR,pBuffer,PASSWORD_MAX_BIT);
  54.                 for(n = 0; n < 4; n++)
  55.                         s_tLock.Password[n] = pBuffer[n];
  56.         }
  57.         
  58.         s_tLock.LockStatus = LOCK;
  59. }

  60. /*
  61. *********************************************************************************************************
  62. *        函 数 名: Run_Lock
  63. *        功能说明: 电子密码锁
  64. *        形    参: 无
  65. *        返 回 值: 无
  66. *********************************************************************************************************
  67. */
  68. void Run_Lock(void)
  69. {        
  70.         LOCK_ENUM LockStatus;
  71.         
  72.         while(1)
  73.         {
  74.                 LockStatus = s_tLock.LockStatus;
  75.                 switch(LockStatus)
  76.                 {
  77.                         case LOCK:
  78.                                 WiatUnlock(&s_tLock);
  79.                                 break;
  80.                         
  81.                         case ISLOCK:
  82.                                 AreUnlock(&s_tLock);
  83.                                 break;
  84.                         
  85.                         case UNLOCK:
  86.                                 HaveUnlock(&s_tLock);
  87.                                 break;
  88.                         
  89.                         case SET_PASSWORD:
  90.                                 SetPassword(&s_tLock);
  91.                                 break;
  92.                         
  93.                         
  94.                         
  95.                         default:
  96.                                 break;
  97.                 }
  98.         }
  99. }


  100. /*
  101. *********************************************************************************************************
  102. *        函 数 名: WiatUnlock
  103. *        功能说明: 等待S3按键按下,进入输入密码状态
  104. *        形    参: p_Lock: LOCK_T结构体
  105. *        返 回 值: 无
  106. *********************************************************************************************************
  107. */
  108. static void WiatUnlock(LOCK_T * p_Lock)
  109. {
  110.         uint8_t KeyState;
  111.         
  112.         for(;;)
  113.         {
  114.                 KeyState = bsp_GetKey();
  115.                 if(KeyState == KEY_DOWN_K3)
  116.                 {
  117.                         p_Lock->LockStatus = ISLOCK;
  118.                         break;
  119.                 }
  120.                 bsp_Display();
  121.         }
  122. }

  123. /*
  124. *********************************************************************************************************
  125. *        函 数 名: AreUnlock
  126. *        功能说明: 进行密码输入
  127. *        形    参: p_Lock: LOCK_T结构体
  128. *        返 回 值: 无
  129. *********************************************************************************************************
  130. */
  131. static void AreUnlock(LOCK_T * p_Lock)
  132. {
  133.         uint8_t KeyState;
  134.         uint8_t n;
  135.         
  136.         
  137.         for(n = 0; n < PASSWORD_MAX_BIT; n++)
  138.                 p_Lock->Input[n] = 0;
  139.         
  140.         p_Lock->Count = 0;
  141.         
  142.         for(;;)
  143.         {
  144.                 KeyState = bsp_GetKey();
  145.                
  146.                 if(KeyState != KEY_NONE)
  147.                 {
  148.                         switch(KeyState)
  149.                         {
  150.                                 case KEY_DOWN_K1:
  151.                                         if(++p_Lock->Input[p_Lock->Count] >= 10)
  152.                                                 p_Lock->Input[p_Lock->Count] = 9;
  153.                                         break;
  154.                                        
  155.                                 case KEY_DOWN_K2:
  156.                                         if(p_Lock->Input[p_Lock->Count]-- <= 0)
  157.                                                 p_Lock->Input[p_Lock->Count] = 0;
  158.                                         break;
  159.                                        
  160.                                 case KEY_DOWN_K3:                /* k3按键短按,用于密码输入时移位 */
  161.                                         if(++p_Lock->Count >= 4)
  162.                                         {
  163.                                                         p_Lock->Count = 0;
  164.                                         }
  165.                                         break;
  166.                                        
  167.                                 case KEY_LONG_K3:                /* k3按键长按,校验输入密码 */
  168.                                         for(n = 0; n < PASSWORD_MAX_BIT; n++)
  169.                                         {
  170.                                                 if(p_Lock->Input[n] != p_Lock->Password[n])
  171.                                                         break;
  172.                                         }
  173.                                         if(n != PASSWORD_MAX_BIT)
  174.                                         {
  175.                                                 p_Lock->LockStatus = PASSWORD_ERR;
  176.                                                 
  177.                                                 //此处添加密码校验错误显示
  178.                                                 bsp_Display();
  179.                                        
  180.                                                 p_Lock->LockStatus = LOCK;
  181.                                         }
  182.                                         else
  183.                                         {
  184.                                                 p_Lock->LockStatus = UNLOCK;
  185.                                         }
  186.                                         break;
  187.                                        
  188.                                 default:
  189.                                         break;
  190.                         }
  191.                 }
  192.                
  193.                 if((p_Lock->LockStatus == UNLOCK) || (p_Lock->LockStatus == LOCK))
  194.                         break;
  195.                
  196.                 bsp_Display();
  197.         }
  198. }

  199. /*
  200. *********************************************************************************************************
  201. *        函 数 名: HaveUnlock
  202. *        功能说明: 密码校验正确,解锁成功
  203. *        形    参: p_Lock: LOCK_T结构体
  204. *        返 回 值: 无
  205. *********************************************************************************************************
  206. */
  207. static void HaveUnlock(LOCK_T * p_Lock)
  208. {
  209.         uint8_t KeyState;
  210.         
  211.         /*
  212.          * 密码校验正确,解锁成功可以在此处调用用户回调函数
  213.          * 回调函数功能一般是开锁
  214.          */
  215.         //p_Lock->callbackFun
  216.         
  217.         for(;;)
  218.         {
  219.                 KeyState = bsp_GetKey();
  220.                
  221.                 if(KeyState != KEY_NONE)
  222.                 {
  223.                         switch(KeyState)
  224.                         {
  225.                                 case KEY_1_DOWN:
  226.                                         p_Lock->LockStatus = LOCK;
  227.                                         break;
  228.                                 
  229.                                 case KEY_2_LONG:
  230.                                         p_Lock->LockStatus = SET_PASSWORD;
  231.                                         break;
  232.                                 
  233.                                 default:
  234.                                         break;
  235.                         }
  236.                 }
  237.                
  238.                 if(p_Lock->LockStatus != UNLOCK)
  239.                         break;
  240.                
  241.                 bsp_Display();
  242.         }
  243. }

  244. /*
  245. *********************************************************************************************************
  246. *        函 数 名: SetPassword
  247. *        功能说明: 重新设置按键密码,只能在开锁之后调用
  248. *        形    参: p_Lock: LOCK_T结构体
  249. *        返 回 值: 无
  250. *********************************************************************************************************
  251. */
  252. static void SetPassword(LOCK_T * p_Lock)
  253. {
  254.         uint8_t KeyState;
  255.         uint8_t n;
  256.         uint8_t Verify, WriteStatus;
  257.         uint8_t bakBuf[PASSWORD_MAX_BIT];
  258.         
  259.         /* 设置之前先备份密码 */
  260.         for(n = 0; n < PASSWORD_MAX_BIT; n++)
  261.                 bakBuf[n] = p_Lock->Password[n];
  262.         
  263.         for(n = 0; n < PASSWORD_MAX_BIT; n++)
  264.                 p_Lock->Password[n] = 0;
  265.         
  266.         p_Lock->Count = 0;
  267.         Verify = CALIBRATION;
  268.         
  269.         for(;;)
  270.         {
  271.                 KeyState = bsp_GetKey();
  272.                
  273.                 if(KeyState != KEY_NONE)
  274.                 {
  275.                         switch(KeyState)
  276.                         {
  277.                                 case KEY_DOWN_K1:
  278.                                         if(++p_Lock->Password[p_Lock->Count] >= 10)
  279.                                                 p_Lock->Password[p_Lock->Count] = 9;
  280.                                         break;
  281.                                 
  282.                                 case KEY_DOWN_K2:
  283.                                         if(p_Lock->Password[p_Lock->Count]-- <= 0)
  284.                                                 p_Lock->Password[p_Lock->Count] = 0;
  285.                                         break;
  286.                                        
  287.                                 case KEY_DOWN_K3:
  288.                                         if(++p_Lock->Count >= 4)
  289.                                                 p_Lock->Count = 0;
  290.                                         break;
  291.                                        
  292.                                 case KEY_LONG_K3:                        /* 长按写入密码到eeprom中 */
  293.                                         //先擦除EEPROM要写入地址扇区,扇区1
  294.                                         EEPROM_SectorErase(PASSWORD_SAVE_ADDR);
  295.                                         //写入新的密码
  296.                                         EEPROM_write_n(PASSWORD_SAVE_ADDR,p_Lock->Password,PASSWORD_MAX_BIT);
  297.                                        
  298.                                         //先擦除EEPROM要写入地址扇区,扇区2
  299.                                         //EEPROM_SectorErase(PASSWORD_IS_MODIFY);
  300.                                         //写入更新标志位
  301.                                         EEPROM_write_n(PASSWORD_IS_MODIFY,&Verify,1);
  302.                                 
  303.                                         //检测是否写入成功
  304.                                         WriteStatus = CheckWriteStatus(p_Lock);
  305.                                        
  306.                                         if(WriteStatus)
  307.                                         {
  308.                                                 s_tLock.LockStatus = WE_PASSWORD_SES;
  309.                                                 //显示写入密码成功
  310.                                                 bsp_Display();
  311.                                         }
  312.                                         else
  313.                                         {
  314.                                                 //显示写入密码失败
  315.                                                 s_tLock.LockStatus = WE_PASSWORD_ERR;
  316.                                 
  317.                                                 //恢复原始密码到Password数组中
  318.                                                 for(n = 0; n < PASSWORD_MAX_BIT; n++)
  319.                                                         p_Lock->Password[n] = bakBuf[n];
  320.                                                 
  321.                                                 //显示写入密码失败
  322.                                                 bsp_Display();
  323.                                         }
  324. ……………………

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

所有资料51hei提供下载:
源代码和PCB.7z (674.28 KB, 下载次数: 71)

评分

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

查看全部评分

回复

使用道具 举报

ID:355122 发表于 2019-3-6 13:31 | 显示全部楼层
有没有仿真
回复

使用道具 举报

ID:128314 发表于 2019-3-6 19:56 | 显示全部楼层

没有仿真,有pcb图和源代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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