找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7290|回复: 4
收起左侧

废弃电子产品拆的LCD12864液晶显示的密码锁制作 附单片机代码

[复制链接]
ID:160658 发表于 2017-3-30 22:06 | 显示全部楼层 |阅读模式
显示和按键都是废物利用, 键盘是电话机外壳改的,做得不太好,别见笑.废话少说,直接上图片.
2.jpg 0.jpg 1.jpg

密码锁的单片机源程序分享到51黑电子:
  1. /********************************************************************************
  2. * 描  述: 密码锁示例
  3. * 备  注:
  4. * 1、用0~9的数字键输入密码,允许的密码最大位数由PSW_MAX_LEN宏定义给出
  5. * 2、用户设定的密码由EEPROM保存,并且用“累加和”校验来保证数据的有效性
  6. * 3、程序首次运行时EEPROM中的数据无效,此时会提示“设置密码”
  7. * 4、设置密码时需要用户输入两次相同的密码,以保证设置成功,设置后密码自动保存
  8. * 5、两次输入密码不相同时,将导致密码设置失败,按回车键重新设置
  9. * 6、密码设置成功后,每次开机都会要求用户输入密码,用户键入密码后,按回车键,
  10.      系统将键入的密码与EEPROM中保存的密码做对比,相同则系统解锁,否则继续锁定
  11. * 7、密码输入错误系统锁定时,按回车键可以重新开始输入密码
  12. * 8、密码输入正确系统解锁时,按回车键可以进入修改密码的操作
  13. * 9、当忘记密码时,可通过修改PSW_MAX_LEN或PSW_SAVE_ADDR宏定义的值来重置密码
  14. ********************************************************************************/
  15. #include <reg52.h>

  16. #define PSW_MAX_LEN    13    //用宏定义出密码最大长度(最大不超过16)
  17. #define PSW_SAVE_ADDR  0x30  //用宏定义出密码在EEPROM中的保存地址
  18. sbit LED = P1^0;
  19. sbit OPEN = P2^7;
  20. unsigned char status = 0;  //系统状态字:0-输入密码,1-设置密码,2-设置密码确认,
  21.                            //3-密码设置失败,4-输入的密码正确,5-输入的密码错误
  22. unsigned char PswCnt;      //当前输入密码位数的计数器
  23. unsigned char  PswSet[PSW_MAX_LEN];   //已设定的密码数据
  24. unsigned char  PswBuf1[PSW_MAX_LEN];  //密码输入缓冲区1
  25. unsigned char  PswBuf2[PSW_MAX_LEN];  //密码输入缓冲区2

  26. unsigned char T0RH = 0;  //T0重载值的高字节
  27. unsigned char T0RL = 0;  //T0重载值的低字节

  28. unsigned char code s0[][32]= {                                                        
  29.         /*--  文字:  请  --*/
  30.         /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  31.         0x40,0x42,0xCC,0x00,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,
  32.         0x00,0x00,0x7F,0x20,0x10,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,
  33.         
  34.         /*--  文字:  输  --*/
  35.         /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  36.         0x88,0x68,0x1F,0xC8,0x08,0x10,0xC8,0x54,0x52,0xD1,0x12,0x94,0x08,0xD0,0x10,0x00,
  37.         0x09,0x19,0x09,0xFF,0x05,0x00,0xFF,0x12,0x92,0xFF,0x00,0x5F,0x80,0x7F,0x00,0x00,
  38.         
  39.         
  40. …………限于本文篇幅 余下代码请从51黑下载附件…………


  41.         /*--  文字:  开  --*/
  42.         /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  43.         0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00,
  44.         0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
  45. };
  46. unsigned char code s1[][16] = {
  47.         0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,          //*
  48. };
  49. bit flagOPEN = 0;
  50. extern bit flagLED;
  51. extern void KeyScan();
  52. extern void KeyDriver();
  53. extern void LCD_ST7567_INIT();
  54. extern void Lcd12864_ON();
  55. extern void        Lcd12864_OFF();
  56. extern void Lcd12864_ClearScreen();
  57. extern void displayPhoto (unsigned char *pic);
  58. extern void z1616(unsigned char plat, unsigned char column, unsigned char p);
  59. extern void WRITE_STRING816(unsigned char plat, unsigned char column, unsigned char p, unsigned char x0[][16], unsigned char c);
  60. extern void E2Read(unsigned char *buf, unsigned char addr, unsigned char len);
  61. extern void E2Write(unsigned char *buf, unsigned char addr, unsigned char len);

  62. void InputCode();
  63. void SetCode();
  64. void DelayM(int ms);
  65. bit  ReadPassword();
  66. void ConfigTimer0(unsigned int ms);
  67. void FillMemory(unsigned char *dest, unsigned char byt, unsigned char len);

  68. void main()
  69. {
  70.         EA = 1;           //开总中断
  71.     ConfigTimer0(1);  //配置T0定时1ms
  72.     LCD_ST7567_INIT();    //初始化液晶
  73.    
  74.         if (ReadPassword())  //读取密码并判断是否有效
  75.     {
  76.         InputCode(); //有效时提示”请输入密码“
  77.         status = 4;
  78.     }
  79.     else
  80.     {
  81.                 SetCode();          //提示”请设置密码“
  82.     }
  83.     FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  84.     FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
  85.     PswCnt = 0;

  86.     while(1)
  87.            {
  88.                  KeyDriver();

  89.                 if(flagLED)
  90.                 {
  91.                         LED = 0;
  92.                         Lcd12864_ON();
  93.                 }
  94.                 else if(flagOPEN)
  95.                 {
  96.                         flagOPEN = 0;
  97.                         Lcd12864_OFF();
  98.                         LED = 1;
  99.                 }
  100.                 else if(status ==5)
  101.                 {
  102.                         Lcd12864_ClearScreen();
  103.             InputCode();
  104.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  105.             PswCnt = 0;
  106.             status = 0;
  107.                 }
  108.         }
  109. }

  110. void SetCode()
  111. {
  112.         z1616(1, 16, 0);
  113.         z1616(1, 32, 5);        
  114.         z1616(1, 48, 6);
  115.         z1616(1, 64, 3);
  116.         z1616(1, 80, 4);  
  117. }

  118. void InputCode()
  119. {
  120.         z1616(1,16,0);        
  121.         z1616(1,32,1);
  122.         z1616(1,48,2);
  123.         z1616(1,64,3);
  124.         z1616(1,80,4);
  125. }

  126. void DelayM(int ms)
  127. {//延时函数 1MS/次        
  128.         unsigned char i;

  129.         while( --ms != 0)
  130.                 {               
  131.                         for(i = 0; i < 125; i++);  //一个 ; 表示空语句,CPU空转。
  132.                 }                                      //i 从0加到125,CPU大概就耗时1毫秒
  133. }
  134. /* 将一段内存数据拷贝到另一处,dest-目的地址,src-源地址,len-数据长度 */
  135. void CopyMemory(unsigned char *dest, unsigned char *src, unsigned char len)
  136. {
  137.     while (len--)
  138.     {
  139.         *dest++ = *src++;
  140.     }
  141. }
  142. /* 用一个指定字节填充一段内存,dest-目的地址,byt-填充用字节,len-数据长度 */
  143. void FillMemory(unsigned char *dest, unsigned char byt, unsigned char len)
  144. {
  145.     while (len--)
  146.     {
  147.         *dest++ = byt;
  148.     }
  149. }
  150. /* 内存比较函数,比较两个指针所指向的内存数据是否相同,
  151.    ptr1-待比较指针1,ptr2-待比较指针2,len-待比较长度
  152.    返回值-两段内存数据完全相同时返回1,不同返回0 */
  153. bit CmpMemory(unsigned char *ptr1, unsigned char *ptr2, unsigned char len)
  154. {
  155.     while (len--)
  156.     {
  157.         if (*ptr1++ != *ptr2++)  //遇到不相等数据时即刻返回0
  158.         {
  159.             return 0;
  160.         }
  161.     }
  162.     return 1;  //比较完全部长度数据都相等则返回1
  163. }
  164. /* 将一段数据按字节累加,返回获得的累加和,dat-数据指针,len-数据长度 */
  165. unsigned char GetChkSum(unsigned char *dat, unsigned char len)
  166. {
  167.     unsigned char sum = 0;
  168.    
  169.     while (len--)
  170.     {
  171.         sum += *dat++;
  172.     }
  173.     return sum;
  174. }
  175. /* 从EEPROM中读取保存的密码数据,并对密码进行“累加和”校验,
  176.    返回值-校验通过返回 1,否则返回 0 */
  177. bit ReadPassword()
  178. {
  179.     unsigned char sum;
  180.     unsigned char buf[PSW_MAX_LEN+1];
  181.    
  182.     E2Read(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1);  //读取密码数据和校验字节
  183.     sum = GetChkSum(buf, PSW_MAX_LEN); //计算密码数据的累加和
  184.     if (buf[PSW_MAX_LEN] == ~sum)      //校验通过,即密码有效时,拷贝密码
  185.     {
  186.         CopyMemory(PswSet, buf, PSW_MAX_LEN);
  187.         return 1;
  188.     }
  189.     else  //密码数据无效时,缓冲区默认成全0
  190.     {
  191.         FillMemory(PswSet, '\0', PSW_MAX_LEN);
  192.         return 0;
  193.     }
  194. }
  195. /* 将当前的密码数据保存到EEPROM中,同时添加校验字节 */
  196. void SavePassword()
  197. {
  198.     unsigned char buf[PSW_MAX_LEN+1];
  199.    
  200.     CopyMemory(buf, PswSet, PSW_MAX_LEN);  //复制密码数据到缓冲区中
  201.     buf[PSW_MAX_LEN] = ~GetChkSum(buf, PSW_MAX_LEN);  //填充最后的累加和校验字节
  202.     E2Write(buf, PSW_SAVE_ADDR, PSW_MAX_LEN+1);  //将密码数据保存到EEPROM中
  203. }
  204. /* 在液晶上显示与当前输入密码位数相同的*,以指示当前输入的密码位数 */
  205. void ShowPswCnt()
  206. {
  207. /*    unsigned char buf[PSW_MAX_LEN+1];
  208.    
  209.     FillMemory(buf, '*', PswCnt);
  210.     FillMemory(buf+PswCnt, '\0', sizeof(buf)-PswCnt);
  211.     LcdShowStr(0, 1, buf);          */
  212.         WRITE_STRING816(2, PswCnt, 0, s1, 0);
  213. }

  214. /* 数字键动作函数,keycode-数字按键的ASCII值 */
  215. void KeyNumAction(unsigned char keycode)
  216. {
  217.     switch (status)
  218.     {
  219.         case 0: //输入密码状态时,将输入字符填充到PswBuf1
  220.             if (PswCnt < PSW_MAX_LEN)
  221.             {
  222.                 PswBuf1[PswCnt] = keycode;
  223.                 PswCnt++;
  224.                 ShowPswCnt();
  225.             }
  226.             break;
  227.         case 1: //设置密码状态时,将输入字符填充到PswBuf1
  228.             if (PswCnt < PSW_MAX_LEN)
  229.             {
  230.                 PswBuf1[PswCnt] = keycode;
  231.                 PswCnt++;
  232.                 ShowPswCnt();
  233.             }
  234.             break;
  235.         case 2: //设置密码确认状态时,将输入字符填充到PswBuf2
  236.             if (PswCnt < PSW_MAX_LEN)
  237.             {
  238.                 PswBuf2[PswCnt] = keycode;
  239.                 PswCnt++;
  240.                 ShowPswCnt();
  241.             }
  242.             break;
  243.         default: //其它状态不予响应
  244.             break;
  245.     }
  246. }
  247. /* 回车键动作函数 */
  248. void KeyEnterAction()
  249. {
  250.         switch (status)
  251.     {
  252.         case 0: //检查输入的密码是否正确
  253.                 Lcd12864_ClearScreen();
  254.             if (CmpMemory(PswSet, PswBuf1, PSW_MAX_LEN))
  255.             {                                     //正确时显示解锁的提示
  256.   //              LcdShowStr(0, 0, "Password Correct");
  257.                                                 
  258.                                 z1616(1,16,3);               
  259.                                 z1616(1,32,4);               
  260.                                 z1616(1,48,7);                //提示 ”密码正确“
  261.                                 z1616(1,64,8);

  262.                                 z1616(2, 64, 14);
  263.                                 z1616(2, 80, 13);        
  264.                                 z1616(2, 96, 17);
  265.                                 z1616(2, 112, 18);        //提示 ”锁已打开“
  266.                                 
  267.                                 OPEN = 0;
  268.                                 DelayM(2000);
  269.                                 OPEN = 1;
  270.                                 status = 5;  //准备下次密码输入状态
  271.             }
  272.                         else
  273.             {   //错误时显示已锁定的提示
  274.    //             LcdShowStr(0, 0, "Password Wrong");
  275.     //            LcdShowStr(0, 1, "system locked");
  276.                                 
  277.                                 z1616(1, 16, 3);        
  278.                                 z1616(1, 32, 4);
  279.                                 z1616(1, 48, 9);        //提示”密码错误“
  280.                                 z1616(1, 64, 10);

  281. /*                                z1616(2, 0, 11);
  282.                                 z1616(2, 16, 12);        
  283.                                 z1616(2, 32, 13);
  284.                                 z1616(2, 48, 14);         //提示”系统已锁“                */
  285.                 status = 5;  //进入锁定状态
  286.                                 DelayM(2000);
  287.             }
  288.             break;
  289.         case 1: //进入密码设置的确认步骤,即再输入一次密码
  290.                 Lcd12864_ClearScreen();
  291.      //       LcdShowStr(0, 0, "Confirm Password");
  292.                         
  293.                         z1616(1, 16, 0);        
  294.                         z1616(1, 32, 15);
  295.                         z1616(1, 48, 16);
  296.                         z1616(1, 64, 1);
  297.                         z1616(1, 80, 2);        
  298.                         z1616(1, 96, 3);        //提示”请再次输入密码“
  299.                         z1616(1, 112, 4);
  300.             
  301.                         PswCnt = 0;
  302.             status = 2;
  303.             break;
  304.         case 2: //检查两次输入的密码是否一致
  305.             Lcd12864_ClearScreen();
  306.             if (CmpMemory(PswBuf1, PswBuf2, PSW_MAX_LEN))
  307.             {   //一致时保存设置的密码
  308. //                LcdShowStr(0, 0, "Enter Password");
  309.                                 InputCode();                //提示”请输入密码“

  310.                 CopyMemory(PswSet, PswBuf1, PSW_MAX_LEN);
  311.                 SavePassword();
  312.                 FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  313.                 PswCnt = 0;
  314.                 status = 0;  //进入密码输入状态
  315.             }
  316.             else
  317.             {   //不一致时提示密码设置错误
  318.    /*            LcdShowStr(0, 0, "Confirm Password");
  319.                                 z1616(1, 0, 0);
  320.                                 z1616(1, 16, 15);        
  321.                                 z1616(1, 32, 16);
  322.                                 z1616(1, 48, 1);
  323.                                 z1616(1, 64, 2);
  324.                                 z1616(1, 80, 3);        
  325.                                 z1616(1, 90, 4);   //提示”请再次输入密码“
  326.    //             LcdShowStr(0, 1, "Failed");                        */
  327.                                 
  328.                                 z1616(1, 16, 3);        
  329.                                 z1616(1, 32, 4);
  330.                                 z1616(1, 48, 5);        
  331.                                 z1616(1, 64, 6);
  332.                                 z1616(1, 80, 9);        //提示”密码设置错误“
  333.                                 z1616(1, 96, 10);

  334.                 status = 3;  //进入密码设置错误状态
  335.             }
  336.             break;
  337.         case 3: //重新提示设置密码,进入密码设置状态
  338.             Lcd12864_ClearScreen();
  339. //           LcdShowStr(0, 0, "Set Password");
  340.                         SetCode();          //提示”请设置密码“

  341.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  342.             FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
  343.             PswCnt = 0;
  344.             status = 1;
  345.             break;
  346.         case 4: //重新设置即修改密码
  347.             Lcd12864_ClearScreen();
  348.   //          LcdShowStr(0, 0, "Set Password");
  349.                         SetCode();         //提示”请设置密码“

  350.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  351.             FillMemory(PswBuf2, '\0', PSW_MAX_LEN);
  352.             PswCnt = 0;
  353.             status = 1;
  354.             break;
  355.         case 5: //重新输入密码
  356.             Lcd12864_ClearScreen();
  357.   //          LcdShowStr(0, 0, "Enter Password");
  358.                         InputCode();         //提示”请输入密码“

  359.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  360.             PswCnt = 0;
  361.             status = 0;
  362.             break;
  363.         default: //不予响应
  364.             break;
  365.     }
  366. }
  367. /* Esc键动作函数 */
  368. void KeyEscAction()
  369. {
  370. //    P2 = 0xFF;
  371.         switch (status)
  372.     {
  373.         case 0: //输入密码状态时,清空当前输入以重新开始
  374.             Lcd12864_ClearScreen();
  375. //            LcdShowStr(0, 0, "Enter Password");
  376.                         InputCode();         //提示”请输入密码“

  377.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  378.             PswCnt = 0;
  379.             break;
  380.         case 1: //设置密码状态时,清空当前输入以重新开始
  381.             Lcd12864_ClearScreen();
  382. //           LcdShowStr(0, 0, "Set Password");
  383.                         SetCode();   //提示”请设置密码“

  384.             FillMemory(PswBuf1, '\0', PSW_MAX_LEN);
  385.             PswCnt = 0;
  386.             break;
  387.         case 2: //设置密码确认状态时,清空输入并返回密码设置状态
  388.             Lcd12864_ClearScreen();
  389.    //         LcdShowStr(0, 0, "Set Password");
  390.                         SetCode();   //提示”请设置密码“


  391. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

0.png

下载:
密码锁.rar (89.53 KB, 下载次数: 26)
回复

使用道具 举报

ID:160658 发表于 2017-3-30 22:08 | 显示全部楼层
上传了附件和程序,怎么没看见了?
回复

使用道具 举报

ID:1 发表于 2017-3-31 05:27 | 显示全部楼层
lern01 发表于 2017-3-30 22:08
上传了附件和程序,怎么没看见了?

已经处理好了,51黑电子论坛的废弃屏幕diy制作又多了一个力作啊.楼主强人.懂得利用各方面的资源,连电话机都用上了.
回复

使用道具 举报

ID:160658 发表于 2017-3-31 11:31 | 显示全部楼层
admin 发表于 2017-3-31 05:27
已经处理好了.楼主强人.懂得利用各方面的资源,连电话机都用 ...

谢谢版主夸奖,手艺还不精
回复

使用道具 举报

ID:960224 发表于 2021-8-12 17:50 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表