找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12715|回复: 19
打印 上一主题 下一主题
收起左侧

单片机密码锁程序+仿真+详细注释

  [复制链接]
跳转到指定楼层
楼主
程序名:密码锁
编写人:   
编写时间:  
硬件支持:STC89C52RC 外部12MHZ晶振
说明备注:
1、输入密码时在LCD屏幕上显示暗码(*),设置管理员密码时显示明码。
2、用户密码3组位5位密码及管理员密码1组。
3、断电保护密码不消失。
4、可手动复位管理员密码及用户密码。
5、输入管理员密码才能修改用户密码,密码不能为6个0,管理员密码需要按复位键进行设置。
6、可指定秀给任意1组的密码。
7、LCD操作步骤提示。
8、密码输入错误3次蜂鸣器报警,输入错误5次键盘锁定(需要复位解锁)。
9、输入管理员密码才能修改用户密码,密码不能为6个0,管理员密码需要按复位键进行设置。
10、按键提示音,开锁音,错误音,报警音。
11、第一次上电强制要求设置管理员密码     


此图片仅供参考

后来用STC12C5A60S2做的 用的是内部集成的eeprom 添加了刷卡开锁+更换为12864屏
因为很多功能不能仿真 没有发上来  


单片机主程序:
  1. /********************************************************************************************/
  2. #include "config.h"
  3. #include "lcd1602.h"
  4. #include "eeprom.h"
  5. #include "LOCK.h"
  6. #include "delay.h"
  7. #include "KEY.h"

  8. void Timer0Init(void);        //50毫秒@12.000MHz
  9. void Timer1Init(void);        //1毫秒@12.000MHz
  10. /********************************************************************************************/
  11. //                        主程序                        //
  12. /********************************************************************************************/
  13. void main(void){

  14.         LOCK=0;                                        //初始化锁关闭状态
  15.         ALAM=1;
  16.         EA=1;                                        //开启总中断
  17.         Timer0Init();                        //50毫秒@12.000MHz
  18.         Timer1Init();                        //1毫秒@12.000MHz
  19.         Delay1ms(400);                 //启动等待,等LCD讲入工作状态
  20.         Init_LCD1602();         //LCD初始化        
  21.         InitLock();                                 //密码锁上电初始化
  22.         while(1){               //进入主循环
  23.                 keyjiance();                //读取按键状态、确定要执行动作
  24.         }
  25. }
  26. void Timer0Init(void){                //50毫秒@12.000MHz
  27.         TMOD &= 0xF0;                        //设置定时器模式
  28.         TMOD |= 0x01;                        //设置定时器模式
  29.         TL0 = 0xB0;                                //设置定时初值
  30.         TH0 = 0x3C;                                //设置定时初值
  31.         TF0 = 0;                                //清除TF0标志
  32.         TR0 = 0;                                //定时器1停止计时
  33.         ET0 = 1;                                //使能T0中断
  34. }
  35. void InterruptTimer0() interrupt 1{
  36.         unsigned char countt0;
  37.         TL0=0xB0;
  38.         TH0=0x3C;                   //定时器重新赋初值
  39.         countt0++;              //计时变量加,加1次时50ms
  40.         if(countt0==20){        //加到20次就是1s
  41.                 countt0=0;          //变量清零
  42.                 second++;           //秒加
  43.                 if(key_disable==1){ //键盘锁状态时
  44.                         if(second==3){  //秒加到1s时
  45.                                 TR0=0;      //关定时器
  46.                                 TL0=0xB0;        //再次赋初值
  47.                                 TH0=0x3C;   //再次赋初值
  48.                                 Cancel0();        //返回--取消所有操作
  49.                                 second=0;   //秒清零
  50.                         }
  51.                 }
  52.                 else{                    //不在键盘锁状态时
  53.                         if(second==6){  //秒加到5时               
  54.                                 TR0=0;      //关闭定时器
  55.                                 second=0;   //秒清零
  56.                                 Cancel0();        //返回--取消所有操作
  57.                                 TL0=0xB0;        //重新赋初值
  58.                                 TH0=0x3C;   //重新赋初值
  59.                         }
  60.                         else
  61.                                 TR0=1;      //打开定时器
  62.                 }                       
  63.     }        
  64. }
  65. void Timer1Init(void){                //1毫秒@12.000MHz
  66.         TMOD &= 0x0F;                        //设置定时器模式
  67.         TMOD |= 0x10;                        //设置定时器模式
  68.         TL1 = 0x18;                                //设置定时初值
  69.         TH1 = 0xFC;                                //设置定时初值
  70.         TF1 = 0;                                //清除TF1标志
  71.         TR1 = 1;                                //定时器1开始计时
  72.         ET1 = 1;                             //使能T1中断
  73. }
  74. //*********************************中断服务函数**************************************
  75. void  time1_int(void) interrupt 3{//定时器T1
  76.         TL1 = 0x18;                                //重置定时初值
  77.         TH1 = 0xFC;                                //重置定时初值
  78.         KeyScan();                                //矩阵键盘扫面
  79. }
复制代码



锁.c :
  1. #include "config.h"
  2. #include "LCD1602.h"
  3. #include "eeprom.h"
  4. #include "delay.h"
  5. #include "KEY.h"
  6. #include "LOCK.h"


  7. bit  pass=0;                                                                        //密码正确标志
  8. bit  ReInputIx=0;                                                                          //重置密码功能标志
  9. bit  ReInputEn=0;                                                                          //重置密码输入允许标志        
  10. bit  key_disable=0;                                                                        //锁定键盘标志
  11. unsigned char ReInputBit = 0;                                         //修改密码第几组标记
  12. unsigned char InputData[6];                                         //输入密码暂存区
  13. unsigned char TempPassword[6];                                                                //修改密码第一遍暂存
  14. unsigned char N=0;                                                                                        //密码输入位数计数
  15. unsigned char ErrorCont = 0;                                        //错误次数计数
  16. unsigned char ReInputCont;                                                 //密码次数输入计数
  17. unsigned char second;                                                                                //t0中断计数器,秒计数器
  18. unsigned char code initpassword[6]={0,0,0,0,0,0};                        //初始化密码
  19. unsigned char CurrentPassword[4][6]={                                                //读取EEPROM密码暂存数组
  20.         {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}
  21.         };

  22. unsigned char code start_line[]      = {"password:       "};//密码
  23. unsigned char code name[]                   = {"===Coded Lock==="};//密码锁   
  24. //=================将按键值编码为数值============================
  25. unsigned char coding(unsigned char m){        
  26.         unsigned char k;
  27.         switch(m){
  28.                 case (0x31): k=1;break;
  29.                 case (0x32): k=2;break;
  30.                 case (0x33): k=3;break;
  31.                 case (0x26): k='A';break;
  32.                 case (0x34): k=4;break;
  33.                 case (0x35): k=5;break;
  34.                 case (0x36): k=6;break;
  35.                 case (0x25): k='B';break;
  36.                 case (0x37): k=7;break;
  37.                 case (0x38): k=8;break;
  38.                 case (0x39): k=9;break;
  39.                 case (0x28): k='C';break;
  40.                 case (0x1B): k='*';break;
  41.                 case (0x30): k=0;break;
  42.                 case (0x0D): k='#';break;
  43.                 case (0x27): k='D';break;
  44.         }
  45.         return(k);
  46. }
  47. //====================一声提示音,表示有效输入===================
  48. void OneAlam(void){
  49.         ALAM=0;
  50.         Delay1ms(50);
  51.     ALAM=1;
  52. }
  53. //====================二声提示音,表示操作成功===================
  54. void TwoAlam(void){
  55.         ALAM=0;
  56.         Delay1ms(50);
  57.     ALAM=1;
  58.     Delay1ms(50);
  59.         ALAM=0;
  60.         Delay1ms(50);
  61.     ALAM=1;
  62. }
  63. //====================三声提示音,表示错误========================
  64. void ThreeAlam(void){
  65.         ALAM=0;
  66.         Delay1ms(50);
  67.     ALAM=1;
  68.     Delay1ms(50);
  69.         ALAM=0;
  70.         Delay1ms(50);
  71.     ALAM=1;
  72.     Delay1ms(50);
  73.         ALAM=0;
  74.         Delay1ms(50);
  75.     ALAM=1;
  76. }
  77. //============输入密码错误超过三过,报警并锁死键盘===============
  78. void Alam_KeyUnable(void){
  79.                 P1=0xFF;
  80.                 ALAM=~ALAM;                                                         //蜂鸣器一直闪烁鸣响
  81.                 Delay1ms(5);
  82. }
  83. //=====================上电初始化=============================
  84. //  1、判断是否上电复位还是按键复位,如果是上电复位 标志位清0退出,
  85. //        2、如果是按键复位,管理员密码及用户密码都清0,
  86. //        3、读出管理员密码 比较管理员密码是否是6个0
  87. //        4、如果管理员密码是6个0,一直等待用户设置管理员密码后再进入下一步
  88. void InitLock(void){
  89.         unsigned char x;

  90.         write_1602com(er+9);    //设置光标位置
  91.         write_1602com(0x0f);    //设置光标为闪烁
  92.         Write1602_ZiFuChuan(1,1,"===Coded Lock===");//向液晶屏写开机画面--英文“密码锁”
  93.         if(0x10==(PCON&0x10)){  //如果上电复位标志为1
  94.                 PCON&=0xEF;                    //上电复位标志清零
  95.         }
  96.         else{                                        //否则判断为外部按键复位,重设管理员密码
  97.                 for(x=0;x<4;x++){
  98.                         E2Write(initpassword,x*8,6);//强制将初始管理员密码及3组用户密码6个0写入24C02存储
  99.                 }               
  100.         }
  101.         Write1602_ZiFuChuan(2,1,"Admin Password: ");//第2行第1位显示“管理员密码    ”
  102.         E2Read(CurrentPassword[0],0,6);        //读出管理员密码
  103.         while(CurrentPassword[0][0]==0){//判断24c02中的管理员密码是否是0---密码6个0无效 ---目的是停在这里让用户修改管理员密码
  104.                 AdminPassword();        //设置管理员密码
  105.                 E2Read(CurrentPassword[0],0,6);//读出管理员密码---以便比较设置好了吗
  106.         }
  107.         Write1602_ZiFuChuan(2,1,"password:       ");//第2行第1位显示“密码    ”
  108.         N=0;                    //将输入数据计数器清零,为输入作准备
  109. }
  110. //====================设置管理员密码=============================
  111. void AdminPassword(void){
  112.         unsigned char j,y,z;
  113.         y=KeyDriver();                                                                                 //读按键的位置码
  114.         if(y!=0){
  115.                 z=coding(y);    //根据按键的位置将其编码,编码值赋值给NUM
  116.                 switch(z){
  117.                         case ('A'):;break;
  118.                         case ('B'):;break;
  119.                         case ('C'):                                                                        //删除最后一个字符  
  120.                                 if(N>=1) N--;                                                          //定位输入的字 加上0的位数               
  121.                                 OneAlam();                                                                 //按键提示音                                                
  122.                                 for(j=N;j<16;j++){
  123.                                         write_1602com(er+6+j);                                //第二行已输入的最后一位
  124.                                         write_1602dat(' ');                                        //显示换成空格
  125.                                 }  
  126.                                 break;                                
  127.                         case ('D'):;break;         
  128.                         case ('*'):;break;                                              //取消当前输入
  129.                         case ('#'):                                                                        //确认键
  130.                                 if(N==6){                                                                //输入满6位
  131.                                         E2Write(InputData,0,6);                                //管理员密码EEPROM存储
  132.                                         TwoAlam();                                                        //成功提示音
  133.                                         break;                                                                //退出循环
  134.                                 }        
  135.                                 else{                                                                         //小于6位报错
  136.                                         Write1602_ZiFuChuan(2,1,"      error     ");//显示错误
  137.                                         ThreeAlam();                                //错误提示音
  138.                                         }
  139.                         default:{                                           //如果不是功能键按下时,就是数字键按下
  140.                                 if(N<6){                                        //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
  141.                                         Write1602_ZiFuChuan(1,1,"====Set Lock====");//第2行第1位显示“管理员密码    ”
  142.                                         Write1602_ZiFuChuan(2,1,"input:          ");//显示输入画面--“输入      ”
  143.                                         OneAlam();                                  //按键有效提示音        
  144.                                         InputData[N]=z;                                   //将数字键的码赋值给InputData[]数组暂存
  145.                                         for(j=0;j<=N;j++){                                        //显示位数随输入增加而增加
  146.                                                 Write1602(0xc0+6+j,InputData[j]+0x30);//第2行但显示实际数字
  147.                                         }
  148.                                         N++;                                        //密码位数加
  149.                                 }
  150.                                 else{                                           //输入数据位数大于6后,忽略输入
  151.                                         N=6;                                            //密码输入大于6位时,不接受输入
  152.                                         break;
  153.                                 }
  154.                         }        
  155.                 }
  156.         }
  157. }
  158. //========================设置密码===============================
  159. void ResetPassword(void){
  160.         unsigned char i;        
  161.                
  162.         ReInputCont++;      //密码次数计数        
  163.         if(ReInputCont==2){ //输入第二次密码时
  164.                 for(i=0;i<6;){        //循环比较2次6位密码是否一致
  165.                         if(TempPassword==InputData)       //将两次输入的新密码作对比
  166.                                         i++;
  167.                         else {                                  //如果两次的密码不同
  168.                                 Write1602_ZiFuChuan(2,1,"      error     ");//显示错误
  169.                                 ThreeAlam();                        //错误提示音
  170.                                 ReInputIx=0;                                         //关闭密码重置功能      
  171.                                 ReInputEn=0;                        //关闭重置输入允许
  172.                                 ReInputCont=0;                                                //密码次数计数清零
  173.                                 break;
  174.                         }
  175.                 }
  176.                 if(i==6){                //2次6位密码一致   -----等待存入位置选择 并确认后存入EEPROM
  177.                         ReInputBit = 1;                                                        //"修改密码第几组标记"标记为第一组                          
  178.                         write_1602com(0x01);                                         //清屏
  179.                         Write1602_ZiFuChuan(1,1,"Select location:");//第1行第1位显示“设置位置”--设置储存在第几组位置(共3组)
  180.                         Write1602_ZiFuChuan(2,1," [1]   [2]   [3]");//第2行分别显示 三组供选择
  181.                         write_1602com(0xc2);                                    //光标在第一组闪烁
  182.                         OneAlam();                              //操作有效提示音
  183.                 }
  184.         ReInputCont=0;                                                                        //密码次数计数清零
  185.         }
  186.         else{             //输入一次密码时                                       
  187.                 OneAlam();                                                                        //操作有效提示音
  188.                 write_1602com(0x01);                                                 //清屏
  189.                 Write1602_ZiFuChuan(1,1,"====Set Lock====");//第1行第1位显示“设置密码”
  190.                 Write1602_ZiFuChuan(2,1,"input again:    ");        //第2行第1位显示“再次输入”
  191.                 for(i=0;i<6;i++){
  192.                         TempPassword=InputData;               //将第一次输入的数据暂存起来                                                
  193.                 }
  194.         }
  195.         N=0;                                                                        //输入数据位数计数器清零
  196. }
  197. //============取消所有操作(定时器0专用)不然有警告================
  198. void Cancel0(void){      
  199.         unsigned char i,j;
  200.                                        
  201.         write_1602com(0x01);                        //清屏
  202.         for(j=0;j<16;j++){        
  203.                 Write1602(yi+j,name[j]);//第1行第1位显示“密码锁”
  204.                 Write1602(er+j,start_line[j]);//第1行第1位显示“密码锁”
  205.         }
  206.         TwoAlam();                          //操作成功提示音
  207.         for(i=0;i<6;i++){        
  208.                 InputData=0;                 //将输入密码清零
  209.         }
  210.         LOCK=0;                         //关闭锁
  211.         ALAM=1;                         //报警关
  212.         pass=0;                         //密码正确标志清零
  213.         ReInputEn=0;                    //重置输入充许标志清零
  214.         ReInputIx=0;                    //密码重置功能标志清零
  215.         ReInputBit=0;                                        //"修改密码第几组标记"清零        
  216.         ErrorCont=0;                    //密码错误输入次数清零
  217.         ReInputCont=0;                  //重置密码输入次数清零
  218.         key_disable=0;                  //锁定键盘标志清零
  219.         N=0;                            //输入位数计数器清零
  220. }
  221. //======================取消所有操作=============================
  222. void Cancel(void){      
  223.         unsigned char i;
  224.                                        
  225.         write_1602com(0x01);                        //清屏
  226.         Write1602_ZiFuChuan(1,1,"===Coded Lock===");//第1行第1位显示“密码锁”
  227.         Write1602_ZiFuChuan(2,1,"password:       ");//第2行第1位显示“密码    ”
  228.         TwoAlam();                          //操作成功提示音
  229.         for(i=0;i<6;i++){        
  230.                 InputData=0;                 //将输入密码清零
  231.         }
复制代码

全部资料51hei下载地址:
密码锁仿真.zip (67.29 KB, 下载次数: 276)
89C52密码锁程序9 24C02 EEPROM.zip (98.06 KB, 下载次数: 277)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏24 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:79544 发表于 2019-11-7 15:24 | 只看该作者
感谢分享。学习啦!!!
回复

使用道具 举报

板凳
ID:639516 发表于 2019-11-11 10:13 | 只看该作者
学习一下
回复

使用道具 举报

地板
ID:634141 发表于 2019-11-24 20:16 | 只看该作者
很好,很喜欢
回复

使用道具 举报

5#
ID:697920 发表于 2020-2-25 15:15 | 只看该作者
您好,可以发一下12864密码锁的程序吗
回复

使用道具 举报

6#
ID:630042 发表于 2020-3-3 22:33 | 只看该作者
谢谢分享
回复

使用道具 举报

7#
ID:777173 发表于 2020-6-12 12:35 | 只看该作者
谢谢分享
回复

使用道具 举报

8#
ID:895480 发表于 2021-3-23 14:24 | 只看该作者
这个单片机主程序头文件不是89c52?
回复

使用道具 举报

9#
ID:895480 发表于 2021-3-23 14:27 | 只看该作者
这个头文件51没有啊
回复

使用道具 举报

10#
ID:100986 发表于 2021-5-21 06:53 | 只看该作者
程序 是一半 一半 ?
回复

使用道具 举报

11#
ID:925919 发表于 2021-5-23 16:11 | 只看该作者
感谢感谢
回复

使用道具 举报

12#
ID:944644 发表于 2021-6-25 15:18 | 只看该作者
hex放在这个目录的 89C52密码锁程序9+24C02 EEPROM\output
回复

使用道具 举报

13#
ID:328014 发表于 2021-6-25 20:18 | 只看该作者
shuck711 发表于 2021-6-25 15:18
为什么下载了,只有仿真图,没有hex文件?

有hex文件,在89C52密码锁程序9+24C02 EEPROM这个文件的output目录里面,如图

51hei.png (6.62 KB, 下载次数: 95)

51hei.png
回复

使用道具 举报

14#
ID:307493 发表于 2021-7-21 15:30 | 只看该作者
读作者的代码有点吃力
回复

使用道具 举报

15#
ID:614285 发表于 2021-7-29 09:46 | 只看该作者
博主太腻害了!
回复

使用道具 举报

16#
ID:994699 发表于 2021-12-26 21:43 | 只看该作者
#include "STC12C5A60S2.h"
运行不了说没有这个咋回事呀?谁能告诉我怎么获取这个文件?
回复

使用道具 举报

17#
ID:815357 发表于 2022-5-18 14:44 来自手机 | 只看该作者
文件里的代码是适用STC12C5A60S2芯片的?我STC89C52RC的打开没反应
回复

使用道具 举报

18#
ID:815357 发表于 2022-5-18 15:32 来自手机 | 只看该作者
所以这个程序是STC89C52RC的还是STC12C5A60S2.h
回复

使用道具 举报

19#
ID:262 发表于 2022-5-19 05:32 | 只看该作者
左视 发表于 2022-5-18 14:44
文件里的代码是适用STC12C5A60S2芯片的?我STC89C52RC的打开没反应

根据楼主提供的仿真来看是12t的单片机的,你看这个仿真图上的型号,所以适用于STC89C52RC芯片,慢慢调试吧,检查你的接线,调整你的LCD的delayd等等

51hei.png (39.96 KB, 下载次数: 69)

51hei.png
回复

使用道具 举报

20#
ID:1042648 发表于 2022-9-7 01:25 | 只看该作者
谢谢分享!我编译出错,郁闷中
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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