|
顯示和按鍵都是廢物利用, 鍵盤是電話機(jī)外殼改的,做得不太好,別見(jiàn)笑.廢話少說(shuō),直接上圖片.
2.jpg (1.04 MB, 下載次數(shù): 110)
下載附件
2017-3-31 05:18 上傳
0.jpg (885.98 KB, 下載次數(shù): 101)
下載附件
2017-3-31 05:18 上傳
1.jpg (653.17 KB, 下載次數(shù): 109)
下載附件
2017-3-31 05:18 上傳
密碼鎖的單片機(jī)源程序分享到51黑電子:
- /********************************************************************************
- * 描 述: 密碼鎖示例
- * 備 注:
- * 1、用0~9的數(shù)字鍵輸入密碼,允許的密碼最大位數(shù)由PSW_MAX_LEN宏定義給出
- * 2、用戶設(shè)定的密碼由EEPROM保存,并且用“累加和”校驗(yàn)來(lái)保證數(shù)據(jù)的有效性
- * 3、程序首次運(yùn)行時(shí)EEPROM中的數(shù)據(jù)無(wú)效,此時(shí)會(huì)提示“設(shè)置密碼”
- * 4、設(shè)置密碼時(shí)需要用戶輸入兩次相同的密碼,以保證設(shè)置成功,設(shè)置后密碼自動(dòng)保存
- * 5、兩次輸入密碼不相同時(shí),將導(dǎo)致密碼設(shè)置失敗,按回車鍵重新設(shè)置
- * 6、密碼設(shè)置成功后,每次開(kāi)機(jī)都會(huì)要求用戶輸入密碼,用戶鍵入密碼后,按回車鍵,
- 系統(tǒng)將鍵入的密碼與EEPROM中保存的密碼做對(duì)比,相同則系統(tǒng)解鎖,否則繼續(xù)鎖定
- * 7、密碼輸入錯(cuò)誤系統(tǒng)鎖定時(shí),按回車鍵可以重新開(kāi)始輸入密碼
- * 8、密碼輸入正確系統(tǒng)解鎖時(shí),按回車鍵可以進(jìn)入修改密碼的操作
- * 9、當(dāng)忘記密碼時(shí),可通過(guò)修改PSW_MAX_LEN或PSW_SAVE_ADDR宏定義的值來(lái)重置密碼
- ********************************************************************************/
- #include <reg52.h>
- #define PSW_MAX_LEN 13 //用宏定義出密碼最大長(zhǎng)度(最大不超過(guò)16)
- #define PSW_SAVE_ADDR 0x30 //用宏定義出密碼在EEPROM中的保存地址
- sbit LED = P1^0;
- sbit OPEN = P2^7;
- unsigned char status = 0; //系統(tǒng)狀態(tài)字:0-輸入密碼,1-設(shè)置密碼,2-設(shè)置密碼確認(rèn),
- //3-密碼設(shè)置失敗,4-輸入的密碼正確,5-輸入的密碼錯(cuò)誤
- unsigned char PswCnt; //當(dāng)前輸入密碼位數(shù)的計(jì)數(shù)器
- unsigned char PswSet[PSW_MAX_LEN]; //已設(shè)定的密碼數(shù)據(jù)
- unsigned char PswBuf1[PSW_MAX_LEN]; //密碼輸入緩沖區(qū)1
- unsigned char PswBuf2[PSW_MAX_LEN]; //密碼輸入緩沖區(qū)2
- unsigned char T0RH = 0; //T0重載值的高字節(jié)
- unsigned char T0RL = 0; //T0重載值的低字節(jié)
- unsigned char code s0[][32]= {
- /*-- 文字: 請(qǐng) --*/
- /*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=16x16 --*/
- 0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,
- 0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,
-
- /*-- 文字: 輸 --*/
- /*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=16x16 --*/
- 0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,
- 0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00,
-
-
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
- /*-- 文字: 開(kāi) --*/
- /*-- 宋體12; 此字體下對(duì)應(yīng)的點(diǎn)陣為:寬x高=16x16 --*/
- 0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00,
- 0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
- };
- unsigned char code s1[][16] = {
- 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00, //*
- };
- bit flagOPEN = 0;
- extern bit flagLED;
- extern void KeyScan();
- extern void KeyDriver();
- extern void LCD_ST7567_INIT();
- extern void Lcd12864_ON();
- extern void Lcd12864_OFF();
- extern void Lcd12864_ClearScreen();
- extern void displayPhoto (unsigned char *pic);
- extern void z1616(unsigned char plat, unsigned char column, unsigned char p);
- extern void WRITE_STRING816(unsigned char plat, unsigned char column, unsigned char p, unsigned char x0[][16], unsigned char c);
- extern void E2Read(unsigned char *buf, unsigned char addr, unsigned char len);
- extern void E2Write(unsigned char *buf, unsigned char addr, unsigned char len);
- void InputCode();
- void SetCode();
- void DelayM(int ms);
- bit ReadPassword();
- void ConfigTimer0(unsigned int ms);
- void FillMemory(unsigned char *dest, unsigned char byt, unsigned char len);
- void main()
- {
- EA = 1; //開(kāi)總中斷
- ConfigTimer0(1); //配置T0定時(shí)1ms
- LCD_ST7567_INIT(); //初始化液晶
-
- if (ReadPassword()) //讀取密碼并判斷是否有效
- {
- InputCode(); //有效時(shí)提示”請(qǐng)輸入密碼“
- status = 4;
- }
- else
- {
- SetCode(); //提示”請(qǐng)?jiān)O(shè)置密碼“
- }
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- while(1)
- {
- KeyDriver();
- if(flagLED)
- {
- LED = 0;
- Lcd12864_ON();
- }
- else if(flagOPEN)
- {
- flagOPEN = 0;
- Lcd12864_OFF();
- LED = 1;
- }
- else if(status ==5)
- {
- Lcd12864_ClearScreen();
- InputCode();
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 0;
- }
- }
- }
- void SetCode()
- {
- z1616(1, 16, 0);
- z1616(1, 32, 5);
- z1616(1, 48, 6);
- z1616(1, 64, 3);
- z1616(1, 80, 4);
- }
- void InputCode()
- {
- z1616(1,16,0);
- z1616(1,32,1);
- z1616(1,48,2);
- z1616(1,64,3);
- z1616(1,80,4);
- }
- void DelayM(int ms)
- {//延時(shí)函數(shù) 1MS/次
- unsigned char i;
- while( --ms != 0)
- {
- for(i = 0; i < 125; i++); //一個(gè) ; 表示空語(yǔ)句,CPU空轉(zhuǎn)。
- } //i 從0加到125,CPU大概就耗時(shí)1毫秒
- }
- /* 將一段內(nèi)存數(shù)據(jù)拷貝到另一處,dest-目的地址,src-源地址,len-數(shù)據(jù)長(zhǎng)度 */
- void CopyMemory(unsigned char *dest, unsigned char *src, unsigned char len)
- {
- while (len--)
- {
- *dest++ = *src++;
- }
- }
- /* 用一個(gè)指定字節(jié)填充一段內(nèi)存,dest-目的地址,byt-填充用字節(jié),len-數(shù)據(jù)長(zhǎng)度 */
- void FillMemory(unsigned char *dest, unsigned char byt, unsigned char len)
- {
- while (len--)
- {
- *dest++ = byt;
- }
- }
- /* 內(nèi)存比較函數(shù),比較兩個(gè)指針?biāo)赶虻膬?nèi)存數(shù)據(jù)是否相同,
- ptr1-待比較指針1,ptr2-待比較指針2,len-待比較長(zhǎng)度
- 返回值-兩段內(nèi)存數(shù)據(jù)完全相同時(shí)返回1,不同返回0 */
- bit CmpMemory(unsigned char *ptr1, unsigned char *ptr2, unsigned char len)
- {
- while (len--)
- {
- if (*ptr1++ != *ptr2++) //遇到不相等數(shù)據(jù)時(shí)即刻返回0
- {
- return 0;
- }
- }
- return 1; //比較完全部長(zhǎng)度數(shù)據(jù)都相等則返回1
- }
- /* 將一段數(shù)據(jù)按字節(jié)累加,返回獲得的累加和,dat-數(shù)據(jù)指針,len-數(shù)據(jù)長(zhǎng)度 */
- unsigned char GetChkSum(unsigned char *dat, unsigned char len)
- {
- unsigned char sum = 0;
-
- while (len--)
- {
- sum += *dat++;
- }
- return sum;
- }
- /* 從EEPROM中讀取保存的密碼數(shù)據(jù),并對(duì)密碼進(jìn)行“累加和”校驗(yàn),
- 返回值-校驗(yàn)通過(guò)返回 1,否則返回 0 */
- bit ReadPassword()
- {
- unsigned char sum;
- unsigned char buf[PSW_MAX_LEN+1];
-
- E2Read(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1); //讀取密碼數(shù)據(jù)和校驗(yàn)字節(jié)
- sum = GetChkSum(buf, PSW_MAX_LEN); //計(jì)算密碼數(shù)據(jù)的累加和
- if (buf[PSW_MAX_LEN] == ~sum) //校驗(yàn)通過(guò),即密碼有效時(shí),拷貝密碼
- {
- CopyMemory(PswSet, buf, PSW_MAX_LEN);
- return 1;
- }
- else //密碼數(shù)據(jù)無(wú)效時(shí),緩沖區(qū)默認(rèn)成全0
- {
- FillMemory(PswSet, '\0', PSW_MAX_LEN);
- return 0;
- }
- }
- /* 將當(dāng)前的密碼數(shù)據(jù)保存到EEPROM中,同時(shí)添加校驗(yàn)字節(jié) */
- void SavePassword()
- {
- unsigned char buf[PSW_MAX_LEN+1];
-
- CopyMemory(buf, PswSet, PSW_MAX_LEN); //復(fù)制密碼數(shù)據(jù)到緩沖區(qū)中
- buf[PSW_MAX_LEN] = ~GetChkSum(buf, PSW_MAX_LEN); //填充最后的累加和校驗(yàn)字節(jié)
- E2Write(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1); //將密碼數(shù)據(jù)保存到EEPROM中
- }
- /* 在液晶上顯示與當(dāng)前輸入密碼位數(shù)相同的*,以指示當(dāng)前輸入的密碼位數(shù) */
- void ShowPswCnt()
- {
- /* unsigned char buf[PSW_MAX_LEN+1];
-
- FillMemory(buf, '*', PswCnt);
- FillMemory(buf+PswCnt, '\0', sizeof(buf)-PswCnt);
- LcdShowStr(0, 1, buf); */
- WRITE_STRING816(2, PswCnt, 0, s1, 0);
- }
- /* 數(shù)字鍵動(dòng)作函數(shù),keycode-數(shù)字按鍵的ASCII值 */
- void KeyNumAction(unsigned char keycode)
- {
- switch (status)
- {
- case 0: //輸入密碼狀態(tài)時(shí),將輸入字符填充到PswBuf1
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf1[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- case 1: //設(shè)置密碼狀態(tài)時(shí),將輸入字符填充到PswBuf1
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf1[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- case 2: //設(shè)置密碼確認(rèn)狀態(tài)時(shí),將輸入字符填充到PswBuf2
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf2[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- default: //其它狀態(tài)不予響應(yīng)
- break;
- }
- }
- /* 回車鍵動(dòng)作函數(shù) */
- void KeyEnterAction()
- {
- switch (status)
- {
- case 0: //檢查輸入的密碼是否正確
- Lcd12864_ClearScreen();
- if (CmpMemory(PswSet, PswBuf1, PSW_MAX_LEN))
- { //正確時(shí)顯示解鎖的提示
- // LcdShowStr(0, 0, "Password Correct");
-
- z1616(1,16,3);
- z1616(1,32,4);
- z1616(1,48,7); //提示 ”密碼正確“
- z1616(1,64,8);
- z1616(2, 64, 14);
- z1616(2, 80, 13);
- z1616(2, 96, 17);
- z1616(2, 112, 18); //提示 ”鎖已打開(kāi)“
-
- OPEN = 0;
- DelayM(2000);
- OPEN = 1;
- status = 5; //準(zhǔn)備下次密碼輸入狀態(tài)
- }
- else
- { //錯(cuò)誤時(shí)顯示已鎖定的提示
- // LcdShowStr(0, 0, "Password Wrong");
- // LcdShowStr(0, 1, "system locked");
-
- z1616(1, 16, 3);
- z1616(1, 32, 4);
- z1616(1, 48, 9); //提示”密碼錯(cuò)誤“
- z1616(1, 64, 10);
- /* z1616(2, 0, 11);
- z1616(2, 16, 12);
- z1616(2, 32, 13);
- z1616(2, 48, 14); //提示”系統(tǒng)已鎖“ */
- status = 5; //進(jìn)入鎖定狀態(tài)
- DelayM(2000);
- }
- break;
- case 1: //進(jìn)入密碼設(shè)置的確認(rèn)步驟,即再輸入一次密碼
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Confirm Password");
-
- z1616(1, 16, 0);
- z1616(1, 32, 15);
- z1616(1, 48, 16);
- z1616(1, 64, 1);
- z1616(1, 80, 2);
- z1616(1, 96, 3); //提示”請(qǐng)?jiān)俅屋斎朊艽a“
- z1616(1, 112, 4);
-
- PswCnt = 0;
- status = 2;
- break;
- case 2: //檢查兩次輸入的密碼是否一致
- Lcd12864_ClearScreen();
- if (CmpMemory(PswBuf1, PswBuf2, PSW_MAX_LEN))
- { //一致時(shí)保存設(shè)置的密碼
- // LcdShowStr(0, 0, "Enter Password");
- InputCode(); //提示”請(qǐng)輸入密碼“
- CopyMemory(PswSet, PswBuf1, PSW_MAX_LEN);
- SavePassword();
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 0; //進(jìn)入密碼輸入狀態(tài)
- }
- else
- { //不一致時(shí)提示密碼設(shè)置錯(cuò)誤
- /* LcdShowStr(0, 0, "Confirm Password");
- z1616(1, 0, 0);
- z1616(1, 16, 15);
- z1616(1, 32, 16);
- z1616(1, 48, 1);
- z1616(1, 64, 2);
- z1616(1, 80, 3);
- z1616(1, 90, 4); //提示”請(qǐng)?jiān)俅屋斎朊艽a“
- // LcdShowStr(0, 1, "Failed"); */
-
- z1616(1, 16, 3);
- z1616(1, 32, 4);
- z1616(1, 48, 5);
- z1616(1, 64, 6);
- z1616(1, 80, 9); //提示”密碼設(shè)置錯(cuò)誤“
- z1616(1, 96, 10);
- status = 3; //進(jìn)入密碼設(shè)置錯(cuò)誤狀態(tài)
- }
- break;
- case 3: //重新提示設(shè)置密碼,進(jìn)入密碼設(shè)置狀態(tài)
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請(qǐng)?jiān)O(shè)置密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 1;
- break;
- case 4: //重新設(shè)置即修改密碼
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請(qǐng)?jiān)O(shè)置密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 1;
- break;
- case 5: //重新輸入密碼
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Enter Password");
- InputCode(); //提示”請(qǐng)輸入密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 0;
- break;
- default: //不予響應(yīng)
- break;
- }
- }
- /* Esc鍵動(dòng)作函數(shù) */
- void KeyEscAction()
- {
- // P2 = 0xFF;
- switch (status)
- {
- case 0: //輸入密碼狀態(tài)時(shí),清空當(dāng)前輸入以重新開(kāi)始
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Enter Password");
- InputCode(); //提示”請(qǐng)輸入密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- break;
- case 1: //設(shè)置密碼狀態(tài)時(shí),清空當(dāng)前輸入以重新開(kāi)始
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請(qǐng)?jiān)O(shè)置密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- break;
- case 2: //設(shè)置密碼確認(rèn)狀態(tài)時(shí),清空輸入并返回密碼設(shè)置狀態(tài)
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請(qǐng)?jiān)O(shè)置密碼“
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
0.png (57.17 KB, 下載次數(shù): 100)
下載附件
2017-3-31 05:19 上傳
下載:
密碼鎖.rar
(89.53 KB, 下載次數(shù): 29)
2017-3-30 22:04 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|