|
這是我上學(xué)期學(xué)校實(shí)訓(xùn)做的電子密碼鎖,主控芯片選擇的是stc15f2k60s2,4位數(shù)碼管作為顯示模塊,設(shè)置密碼存放在單片機(jī)內(nèi)部的eeprom中。附件中包含4位電子密碼鎖的原理圖和PCB設(shè)計以及源代碼,分享給大家,希望大家一起進(jìn)步。
密碼鎖的詳細(xì)的操作說明如下:
1、密碼鎖初始密碼是2019,密碼修改成功后一定要記住自己設(shè)置密碼,否則下次不能正常
開鎖。
2、初始上電情況下,密碼鎖處于關(guān)閉狀態(tài),數(shù)碼管顯示"OFF"。此時短按按鍵S3進(jìn)入輸入
密碼狀態(tài)。通過按鍵完成4位密碼的輸入,s1按鍵代表加,s2按鍵代表減,s3按鍵代表移
位(通過s3按鍵完成不同密碼位的切換輸入),當(dāng)四位密碼輸入完成后,長按s3按鍵,系統(tǒng)
進(jìn)行輸入密碼和實(shí)際密碼的校驗(yàn)
3、輸入密碼正確,密碼鎖進(jìn)入開鎖狀態(tài),數(shù)碼管顯示"OPEN"。此時短按按鍵s1(正常按下),
密碼鎖進(jìn)入關(guān)閉狀態(tài),數(shù)碼管顯示"OFF"。輸入密碼錯誤,數(shù)碼管上閃爍'----'4次,然后顯
示OFF想要再次開鎖還需重復(fù)2的操作。
4、密碼鎖只有處于開鎖狀態(tài)情況下才能設(shè)置新的密碼。密碼鎖處于開鎖狀態(tài)下,長按(一直按
住按鍵,直到數(shù)碼管提示密碼輸入)S2按鍵進(jìn)入設(shè)置新密碼狀態(tài)。新密碼輸入完成后,長按
S3鍵,密碼保存到EEPROM中。如果新密碼設(shè)置成功,數(shù)碼管上會閃爍"666"4次,然后顯示
OPEN;如果新密碼設(shè)置失敗,數(shù)碼管會閃爍 "FFFF"4次,然后顯示OPEN。設(shè)置新密碼失敗如
果重新設(shè)置密碼鎖,重復(fù)步驟3操作。
實(shí)物圖
密碼鎖關(guān)閉
輸入密碼
密碼鎖打開
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
+-------------------------------------------------------------------+
* + 由于按鍵資源有限,某些按鍵必須支持復(fù)用功能,長按、短按操作一 +
* + 定要注意 +
+ S1按鍵---------------->P0.5端口 +
* + S2按鍵---------------->P0.6端口 +
* + S3按鍵---------------->P0.7端口 +
* + +
* + 本代碼完全按照實(shí)驗(yàn)提供原理圖編寫,如果你在設(shè)置硬件時更改原理 +
* + 圖(可能是因?yàn)樘峁┰韴D 單層布線完全),你需要根據(jù)自己原理圖 +
* + 更改數(shù)碼管位選和段選(bsp_smg.c文件) +
* +-------------------------------------------------------------------+
單片機(jī)程序代碼如下:
- /*
- *********************************************************************************************************
- *
- * 模塊名稱 : 電子密碼鎖核心模塊。
- * 文件名稱 : code_lock.c
- * 版 本 : V1.0
- * 說 明 : 電子密碼鎖
- *
- *
- *********************************************************************************************************
- */
- #include "bsp.h"
- #include "code_lock.h"
- #define SUCCESS 1
- #define FALSE 0
- #define CALIBRATION 0x80
- /* 第一個扇區(qū)EEPROM的起始地址 */
- #define PASSWORD_SAVE_ADDR 0x00 /* 密碼存放在單片機(jī)EEPROM中初始地址 */
- /* 第二個扇區(qū)EEPROM的起始地址 */
- #define PASSWORD_IS_MODIFY 0x300 /* 讀取此地址內(nèi)容,判斷默認(rèn)密碼是否被
- 修改,如果被修改每次上電后必須從密
- 碼存放地址處讀取密碼,并將其存放到結(jié)
- 構(gòu)體成員變量password數(shù)組中 */
-
- 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);
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: 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地址內(nèi)容,判斷默認(rèn)密碼是否被修改 */
- EEPROM_read_n(PASSWORD_IS_MODIFY,&tmp,1);
- /* 默認(rèn)密碼已經(jīng)被修改,從eeprom中讀入密碼到password數(shù)組 */
- 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;
- }
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: 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;
- }
- }
- }
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: WiatUnlock
- * 功能說明: 等待S3按鍵按下,進(jìn)入輸入密碼狀態(tài)
- * 形 參: p_Lock: LOCK_T結(jié)構(gòu)體
- * 返 回 值: 無
- *********************************************************************************************************
- */
- 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();
- }
- }
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: AreUnlock
- * 功能說明: 進(jìn)行密碼輸入
- * 形 參: p_Lock: LOCK_T結(jié)構(gòu)體
- * 返 回 值: 無
- *********************************************************************************************************
- */
- 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按鍵長按,校驗(yàn)輸入密碼 */
- 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;
-
- //此處添加密碼校驗(yàn)錯誤顯示
- 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();
- }
- }
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: HaveUnlock
- * 功能說明: 密碼校驗(yàn)正確,解鎖成功
- * 形 參: p_Lock: LOCK_T結(jié)構(gòu)體
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static void HaveUnlock(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
-
- /*
- * 密碼校驗(yàn)正確,解鎖成功可以在此處調(diào)用用戶回調(diào)函數(shù)
- * 回調(diào)函數(shù)功能一般是開鎖
- */
- //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();
- }
- }
- /*
- *********************************************************************************************************
- * 函 數(shù) 名: SetPassword
- * 功能說明: 重新設(shè)置按鍵密碼,只能在開鎖之后調(diào)用
- * 形 參: p_Lock: LOCK_T結(jié)構(gòu)體
- * 返 回 值: 無
- *********************************************************************************************************
- */
- static void SetPassword(LOCK_T * p_Lock)
- {
- uint8_t KeyState;
- uint8_t n;
- uint8_t Verify, WriteStatus;
- uint8_t bakBuf[PASSWORD_MAX_BIT];
-
- /* 設(shè)置之前先備份密碼 */
- 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要寫入地址扇區(qū),扇區(qū)1
- EEPROM_SectorErase(PASSWORD_SAVE_ADDR);
- //寫入新的密碼
- EEPROM_write_n(PASSWORD_SAVE_ADDR,p_Lock->Password,PASSWORD_MAX_BIT);
-
- //先擦除EEPROM要寫入地址扇區(qū),扇區(qū)2
- //EEPROM_SectorErase(PASSWORD_IS_MODIFY);
- //寫入更新標(biāo)志位
- 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;
-
- //恢復(fù)原始密碼到Password數(shù)組中
- for(n = 0; n < PASSWORD_MAX_BIT; n++)
- p_Lock->Password[n] = bakBuf[n];
-
- //顯示寫入密碼失敗
- bsp_Display();
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
源代碼和PCB.7z
(674.28 KB, 下載次數(shù): 71)
2019-3-6 01:28 上傳
點(diǎn)擊文件名下載附件
|
評分
-
查看全部評分
|