顯示和按鍵都是廢物利用, 鍵盤是電話機外殼改的,做得不太好,別見笑.廢話少說,直接上圖片.
2.jpg (1.04 MB, 下載次數: 110)
下載附件
2017-3-31 05:18 上傳
0.jpg (885.98 KB, 下載次數: 101)
下載附件
2017-3-31 05:18 上傳
1.jpg (653.17 KB, 下載次數: 109)
下載附件
2017-3-31 05:18 上傳
密碼鎖的單片機源程序分享到51黑電子:
- /********************************************************************************
- * 描 述: 密碼鎖示例
- * 備 注:
- * 1、用0~9的數字鍵輸入密碼,允許的密碼最大位數由PSW_MAX_LEN宏定義給出
- * 2、用戶設定的密碼由EEPROM保存,并且用“累加和”校驗來保證數據的有效性
- * 3、程序首次運行時EEPROM中的數據無效,此時會提示“設置密碼”
- * 4、設置密碼時需要用戶輸入兩次相同的密碼,以保證設置成功,設置后密碼自動保存
- * 5、兩次輸入密碼不相同時,將導致密碼設置失敗,按回車鍵重新設置
- * 6、密碼設置成功后,每次開機都會要求用戶輸入密碼,用戶鍵入密碼后,按回車鍵,
- 系統將鍵入的密碼與EEPROM中保存的密碼做對比,相同則系統解鎖,否則繼續鎖定
- * 7、密碼輸入錯誤系統鎖定時,按回車鍵可以重新開始輸入密碼
- * 8、密碼輸入正確系統解鎖時,按回車鍵可以進入修改密碼的操作
- * 9、當忘記密碼時,可通過修改PSW_MAX_LEN或PSW_SAVE_ADDR宏定義的值來重置密碼
- ********************************************************************************/
- #include <reg52.h>
- #define PSW_MAX_LEN 13 //用宏定義出密碼最大長度(最大不超過16)
- #define PSW_SAVE_ADDR 0x30 //用宏定義出密碼在EEPROM中的保存地址
- sbit LED = P1^0;
- sbit OPEN = P2^7;
- unsigned char status = 0; //系統狀態字:0-輸入密碼,1-設置密碼,2-設置密碼確認,
- //3-密碼設置失敗,4-輸入的密碼正確,5-輸入的密碼錯誤
- unsigned char PswCnt; //當前輸入密碼位數的計數器
- unsigned char PswSet[PSW_MAX_LEN]; //已設定的密碼數據
- unsigned char PswBuf1[PSW_MAX_LEN]; //密碼輸入緩沖區1
- unsigned char PswBuf2[PSW_MAX_LEN]; //密碼輸入緩沖區2
- unsigned char T0RH = 0; //T0重載值的高字節
- unsigned char T0RL = 0; //T0重載值的低字節
- unsigned char code s0[][32]= {
- /*-- 文字: 請 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬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; 此字體下對應的點陣為:寬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,
-
-
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
- /*-- 文字: 開 --*/
- /*-- 宋體12; 此字體下對應的點陣為:寬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; //開總中斷
- ConfigTimer0(1); //配置T0定時1ms
- LCD_ST7567_INIT(); //初始化液晶
-
- if (ReadPassword()) //讀取密碼并判斷是否有效
- {
- InputCode(); //有效時提示”請輸入密碼“
- status = 4;
- }
- else
- {
- SetCode(); //提示”請設置密碼“
- }
- 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)
- {//延時函數 1MS/次
- unsigned char i;
- while( --ms != 0)
- {
- for(i = 0; i < 125; i++); //一個 ; 表示空語句,CPU空轉。
- } //i 從0加到125,CPU大概就耗時1毫秒
- }
- /* 將一段內存數據拷貝到另一處,dest-目的地址,src-源地址,len-數據長度 */
- void CopyMemory(unsigned char *dest, unsigned char *src, unsigned char len)
- {
- while (len--)
- {
- *dest++ = *src++;
- }
- }
- /* 用一個指定字節填充一段內存,dest-目的地址,byt-填充用字節,len-數據長度 */
- void FillMemory(unsigned char *dest, unsigned char byt, unsigned char len)
- {
- while (len--)
- {
- *dest++ = byt;
- }
- }
- /* 內存比較函數,比較兩個指針所指向的內存數據是否相同,
- ptr1-待比較指針1,ptr2-待比較指針2,len-待比較長度
- 返回值-兩段內存數據完全相同時返回1,不同返回0 */
- bit CmpMemory(unsigned char *ptr1, unsigned char *ptr2, unsigned char len)
- {
- while (len--)
- {
- if (*ptr1++ != *ptr2++) //遇到不相等數據時即刻返回0
- {
- return 0;
- }
- }
- return 1; //比較完全部長度數據都相等則返回1
- }
- /* 將一段數據按字節累加,返回獲得的累加和,dat-數據指針,len-數據長度 */
- unsigned char GetChkSum(unsigned char *dat, unsigned char len)
- {
- unsigned char sum = 0;
-
- while (len--)
- {
- sum += *dat++;
- }
- return sum;
- }
- /* 從EEPROM中讀取保存的密碼數據,并對密碼進行“累加和”校驗,
- 返回值-校驗通過返回 1,否則返回 0 */
- bit ReadPassword()
- {
- unsigned char sum;
- unsigned char buf[PSW_MAX_LEN+1];
-
- E2Read(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1); //讀取密碼數據和校驗字節
- sum = GetChkSum(buf, PSW_MAX_LEN); //計算密碼數據的累加和
- if (buf[PSW_MAX_LEN] == ~sum) //校驗通過,即密碼有效時,拷貝密碼
- {
- CopyMemory(PswSet, buf, PSW_MAX_LEN);
- return 1;
- }
- else //密碼數據無效時,緩沖區默認成全0
- {
- FillMemory(PswSet, '\0', PSW_MAX_LEN);
- return 0;
- }
- }
- /* 將當前的密碼數據保存到EEPROM中,同時添加校驗字節 */
- void SavePassword()
- {
- unsigned char buf[PSW_MAX_LEN+1];
-
- CopyMemory(buf, PswSet, PSW_MAX_LEN); //復制密碼數據到緩沖區中
- buf[PSW_MAX_LEN] = ~GetChkSum(buf, PSW_MAX_LEN); //填充最后的累加和校驗字節
- E2Write(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1); //將密碼數據保存到EEPROM中
- }
- /* 在液晶上顯示與當前輸入密碼位數相同的*,以指示當前輸入的密碼位數 */
- 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);
- }
- /* 數字鍵動作函數,keycode-數字按鍵的ASCII值 */
- void KeyNumAction(unsigned char keycode)
- {
- switch (status)
- {
- case 0: //輸入密碼狀態時,將輸入字符填充到PswBuf1
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf1[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- case 1: //設置密碼狀態時,將輸入字符填充到PswBuf1
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf1[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- case 2: //設置密碼確認狀態時,將輸入字符填充到PswBuf2
- if (PswCnt < PSW_MAX_LEN)
- {
- PswBuf2[PswCnt] = keycode;
- PswCnt++;
- ShowPswCnt();
- }
- break;
- default: //其它狀態不予響應
- break;
- }
- }
- /* 回車鍵動作函數 */
- void KeyEnterAction()
- {
- switch (status)
- {
- case 0: //檢查輸入的密碼是否正確
- Lcd12864_ClearScreen();
- if (CmpMemory(PswSet, PswBuf1, PSW_MAX_LEN))
- { //正確時顯示解鎖的提示
- // 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); //提示 ”鎖已打開“
-
- OPEN = 0;
- DelayM(2000);
- OPEN = 1;
- status = 5; //準備下次密碼輸入狀態
- }
- else
- { //錯誤時顯示已鎖定的提示
- // LcdShowStr(0, 0, "Password Wrong");
- // LcdShowStr(0, 1, "system locked");
-
- z1616(1, 16, 3);
- z1616(1, 32, 4);
- z1616(1, 48, 9); //提示”密碼錯誤“
- z1616(1, 64, 10);
- /* z1616(2, 0, 11);
- z1616(2, 16, 12);
- z1616(2, 32, 13);
- z1616(2, 48, 14); //提示”系統已鎖“ */
- status = 5; //進入鎖定狀態
- DelayM(2000);
- }
- break;
- case 1: //進入密碼設置的確認步驟,即再輸入一次密碼
- 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); //提示”請再次輸入密碼“
- z1616(1, 112, 4);
-
- PswCnt = 0;
- status = 2;
- break;
- case 2: //檢查兩次輸入的密碼是否一致
- Lcd12864_ClearScreen();
- if (CmpMemory(PswBuf1, PswBuf2, PSW_MAX_LEN))
- { //一致時保存設置的密碼
- // LcdShowStr(0, 0, "Enter Password");
- InputCode(); //提示”請輸入密碼“
- CopyMemory(PswSet, PswBuf1, PSW_MAX_LEN);
- SavePassword();
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 0; //進入密碼輸入狀態
- }
- else
- { //不一致時提示密碼設置錯誤
- /* 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); //提示”請再次輸入密碼“
- // LcdShowStr(0, 1, "Failed"); */
-
- z1616(1, 16, 3);
- z1616(1, 32, 4);
- z1616(1, 48, 5);
- z1616(1, 64, 6);
- z1616(1, 80, 9); //提示”密碼設置錯誤“
- z1616(1, 96, 10);
- status = 3; //進入密碼設置錯誤狀態
- }
- break;
- case 3: //重新提示設置密碼,進入密碼設置狀態
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請設置密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 1;
- break;
- case 4: //重新設置即修改密碼
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請設置密碼“
- 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(); //提示”請輸入密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- status = 0;
- break;
- default: //不予響應
- break;
- }
- }
- /* Esc鍵動作函數 */
- void KeyEscAction()
- {
- // P2 = 0xFF;
- switch (status)
- {
- case 0: //輸入密碼狀態時,清空當前輸入以重新開始
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Enter Password");
- InputCode(); //提示”請輸入密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- break;
- case 1: //設置密碼狀態時,清空當前輸入以重新開始
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請設置密碼“
- FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
- PswCnt = 0;
- break;
- case 2: //設置密碼確認狀態時,清空輸入并返回密碼設置狀態
- Lcd12864_ClearScreen();
- // LcdShowStr(0, 0, "Set Password");
- SetCode(); //提示”請設置密碼“
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (57.17 KB, 下載次數: 100)
下載附件
2017-3-31 05:19 上傳
下載:
密碼鎖.rar
(89.53 KB, 下載次數: 29)
2017-3-30 22:04 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|