这是我上学期学校实训做的电子密码锁,主控芯片选择的是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附件中可下载工程文件)
+-------------------------------------------------------------------+
* + 由于按键资源有限,某些按键必须支持复用功能,长按、短按操作一 +
* + 定要注意 +
+ S1按键---------------->P0.5端口 +
* + S2按键---------------->P0.6端口 +
* + S3按键---------------->P0.7端口 +
* + +
* + 本代码完全按照实验提供原理图编写,如果你在设置硬件时更改原理 +
* + 图(可能是因为提供原理图 单层布线完全),你需要根据自己原理图 +
* + 更改数码管位选和段选(bsp_smg.c文件) +
* +-------------------------------------------------------------------+
单片机程序代码如下:
- /*
- *********************************************************************************************************
- *
- * 模块名称 : 电子密码锁核心模块。
- * 文件名称 : code_lock.c
- * 版 本 : V1.0
- * 说 明 : 电子密码锁
- *
- *
- *********************************************************************************************************
- */
- #include "bsp.h"
- #include "code_lock.h"
- #define SUCCESS 1
- #define FALSE 0
- #define CALIBRATION 0x80
- /* 第一个扇区EEPROM的起始地址 */
- #define PASSWORD_SAVE_ADDR 0x00 /* 密码存放在单片机EEPROM中初始地址 */
- /* 第二个扇区EEPROM的起始地址 */
- #define PASSWORD_IS_MODIFY 0x300 /* 读取此地址内容,判断默认密码是否被
- 修改,如果被修改每次上电后必须从密
- 码存放地址处读取密码,并将其存放到结
- 构体成员变量password数组中 */
-
- LOCK_T s_tLock;
- static void WiatUnlock(LOCK_T * p_Lock);
- static void AreUnlock(LOCK_T * p_Lock);
- static void HaveUnlock(LOCK_T * p_Lock);
- static void SetPassword(LOCK_T * p_Lock);
- static uint8_t CheckWriteStatus(LOCK_T * p_Lock);
- /*
- *********************************************************************************************************
- * 函 数 名: Init_Lock_Var
- * 功能说明: 初始化密码锁初始密码
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void Init_Lock(void)
- {
- uint8_t tmp;
- uint8_t pBuffer[PASSWORD_MAX_BIT] = {2, 0, 1, 9};
- uint8_t n;
-
- for(n = 0; n < 4; n++)
- s_tLock.Password[n] = pBuffer[n];
-
- /* 读取PASSWORD_IS_MODIFY地址内容,判断默认密码是否被修改 */
- EEPROM_read_n(PASSWORD_IS_MODIFY,&tmp,1);
- /* 默认密码已经被修改,从eeprom中读入密码到password数组 */
- if(tmp == CALIBRATION)
- {
- EEPROM_read_n(PASSWORD_SAVE_ADDR,pBuffer,PASSWORD_MAX_BIT);
- for(n = 0; n < 4; n++)
- s_tLock.Password[n] = pBuffer[n];
- }
-
- s_tLock.LockStatus = LOCK;
- }
- /*
- *********************************************************************************************************
- * 函 数 名: Run_Lock
- * 功能说明: 电子密码锁
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void Run_Lock(void)
- {
- LOCK_ENUM LockStatus;
-
- while(1)
- {
- LockStatus = s_tLock.LockStatus;
- switch(LockStatus)
- {
- case LOCK:
- WiatUnlock(&s_tLock);
- break;
-
- case ISLOCK:
- AreUnlock(&s_tLock);
- break;
-
- case UNLOCK:
- HaveUnlock(&s_tLock);
- break;
-
- case SET_PASSWORD:
- SetPassword(&s_tLock);
- break;
-
-
-
- default:
- break;
- }
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: WiatUnlock
- * 功能说明: 等待S3按键按下,进入输入密码状态
- * 形 参: p_Lock: LOCK_T结构体
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void WiatUnlock(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
-
- for(;;)
- {
- KeyState = bsp_GetKey();
- if(KeyState == KEY_DOWN_K3)
- {
- p_Lock->LockStatus = ISLOCK;
- break;
- }
- bsp_Display();
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: AreUnlock
- * 功能说明: 进行密码输入
- * 形 参: p_Lock: LOCK_T结构体
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AreUnlock(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
- uint8_t n;
-
-
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- p_Lock->Input[n] = 0;
-
- p_Lock->Count = 0;
-
- for(;;)
- {
- KeyState = bsp_GetKey();
-
- if(KeyState != KEY_NONE)
- {
- switch(KeyState)
- {
- case KEY_DOWN_K1:
- if(++p_Lock->Input[p_Lock->Count] >= 10)
- p_Lock->Input[p_Lock->Count] = 9;
- break;
-
- case KEY_DOWN_K2:
- if(p_Lock->Input[p_Lock->Count]-- <= 0)
- p_Lock->Input[p_Lock->Count] = 0;
- break;
-
- case KEY_DOWN_K3: /* k3按键短按,用于密码输入时移位 */
- if(++p_Lock->Count >= 4)
- {
- p_Lock->Count = 0;
- }
- break;
-
- case KEY_LONG_K3: /* k3按键长按,校验输入密码 */
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- {
- if(p_Lock->Input[n] != p_Lock->Password[n])
- break;
- }
- if(n != PASSWORD_MAX_BIT)
- {
- p_Lock->LockStatus = PASSWORD_ERR;
-
- //此处添加密码校验错误显示
- bsp_Display();
-
- p_Lock->LockStatus = LOCK;
- }
- else
- {
- p_Lock->LockStatus = UNLOCK;
- }
- break;
-
- default:
- break;
- }
- }
-
- if((p_Lock->LockStatus == UNLOCK) || (p_Lock->LockStatus == LOCK))
- break;
-
- bsp_Display();
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: HaveUnlock
- * 功能说明: 密码校验正确,解锁成功
- * 形 参: p_Lock: LOCK_T结构体
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void HaveUnlock(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
-
- /*
- * 密码校验正确,解锁成功可以在此处调用用户回调函数
- * 回调函数功能一般是开锁
- */
- //p_Lock->callbackFun
-
- for(;;)
- {
- KeyState = bsp_GetKey();
-
- if(KeyState != KEY_NONE)
- {
- switch(KeyState)
- {
- case KEY_1_DOWN:
- p_Lock->LockStatus = LOCK;
- break;
-
- case KEY_2_LONG:
- p_Lock->LockStatus = SET_PASSWORD;
- break;
-
- default:
- break;
- }
- }
-
- if(p_Lock->LockStatus != UNLOCK)
- break;
-
- bsp_Display();
- }
- }
- /*
- *********************************************************************************************************
- * 函 数 名: SetPassword
- * 功能说明: 重新设置按键密码,只能在开锁之后调用
- * 形 参: p_Lock: LOCK_T结构体
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void SetPassword(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
- uint8_t n;
- uint8_t Verify, WriteStatus;
- uint8_t bakBuf[PASSWORD_MAX_BIT];
-
- /* 设置之前先备份密码 */
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- bakBuf[n] = p_Lock->Password[n];
-
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- p_Lock->Password[n] = 0;
-
- p_Lock->Count = 0;
- Verify = CALIBRATION;
-
- for(;;)
- {
- KeyState = bsp_GetKey();
-
- if(KeyState != KEY_NONE)
- {
- switch(KeyState)
- {
- case KEY_DOWN_K1:
- if(++p_Lock->Password[p_Lock->Count] >= 10)
- p_Lock->Password[p_Lock->Count] = 9;
- break;
-
- case KEY_DOWN_K2:
- if(p_Lock->Password[p_Lock->Count]-- <= 0)
- p_Lock->Password[p_Lock->Count] = 0;
- break;
-
- case KEY_DOWN_K3:
- if(++p_Lock->Count >= 4)
- p_Lock->Count = 0;
- break;
-
- case KEY_LONG_K3: /* 长按写入密码到eeprom中 */
- //先擦除EEPROM要写入地址扇区,扇区1
- EEPROM_SectorErase(PASSWORD_SAVE_ADDR);
- //写入新的密码
- EEPROM_write_n(PASSWORD_SAVE_ADDR,p_Lock->Password,PASSWORD_MAX_BIT);
-
- //先擦除EEPROM要写入地址扇区,扇区2
- //EEPROM_SectorErase(PASSWORD_IS_MODIFY);
- //写入更新标志位
- EEPROM_write_n(PASSWORD_IS_MODIFY,&Verify,1);
-
- //检测是否写入成功
- WriteStatus = CheckWriteStatus(p_Lock);
-
- if(WriteStatus)
- {
- s_tLock.LockStatus = WE_PASSWORD_SES;
- //显示写入密码成功
- bsp_Display();
- }
- else
- {
- //显示写入密码失败
- s_tLock.LockStatus = WE_PASSWORD_ERR;
-
- //恢复原始密码到Password数组中
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- p_Lock->Password[n] = bakBuf[n];
-
- //显示写入密码失败
- bsp_Display();
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
源代码和PCB.7z
(674.28 KB, 下载次数: 71)
|