显示和按键都是废物利用, 键盘是电话机外壳改的,做得不太好,别见笑.废话少说,直接上图片.
密码锁的单片机源程序分享到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黑下载附件…………
复制代码
下载:
密码锁.rar
(89.53 KB, 下载次数: 29)
|