找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机密码锁程序无法更改密码的问题

[复制链接]
ID:76027 发表于 2024-5-15 14:00 | 显示全部楼层 |阅读模式
最近按论坛上的例程,做了一个密码锁。按原例程的本意,应该是下载程序第一次使用时,要初始化密码。现在是没有初始化直接用CurrentPassword[6]数组可以打开密码锁,在打开密码锁的情况下,再次输入CurrentPassword[6]数组,可以进入更改密码画面,输入二次新密码后,显示密码更改成功,但新密码无法打开密码锁。下面是部分代码,完整的代码在这里:密码锁
  1. /========================重置密码==================================================
  2. //==================================================================================
  3. void ResetPassword(void)
  4. {
  5.         unsigned char i;      
  6.         unsigned char j;
  7.         if(pass==0)
  8.         {
  9.                 pass=0;                          
  10.                 DisplayChar();           //显示错误
  11.                 ThreeAlam();           //没开锁时按下重置密码报警3声
  12.         }
  13.         else                                   //开锁状态下才能进行密码重置程序
  14.         {
  15.             if(ReInputEn==1)   //开锁状态下,ReInputEn置1,重置密码允许
  16.                 {
  17.                         if(N==6)           //输入6位密码
  18.                         {
  19.                                 ReInputCont++;                        //密码次数计数      
  20.                                 if(ReInputCont==2)                //输入两次密码
  21.                                 {
  22.                                         for(i=0;i<6;)
  23.                                         {
  24.                                                 if(TempPassword[i]==InputData[i])        //将两次输入的新密码作对比
  25.                                                         i++;
  26.                                                 else                                                                //如果两次的密码不同
  27.                                                 {
  28.                                                         //DisplayListChar(0,1,Error);
  29.                                                         write_1602com(er);
  30.                                                         for(j=0;j<16;j++)
  31.                                                         {
  32.                                                                 write_1602dat(Error[j]);        //显示错误Error
  33.                                                         }
  34.                                                         ThreeAlam();                        //错误提示      
  35.                                                         pass=0;                                        //关锁
  36.                                                         ReInputEn=0;                        //关闭重置功能,
  37.                                                         ReInputCont=0;
  38.                                                         DisplayChar();
  39.                                                         break;
  40.                                                 }
  41.                                         }
  42.                                         if(i==6)
  43.                                         {
  44.                                                 //DisplayListChar(0,1,ResetOK);
  45.                                                 write_1602com(er);
  46.                                                 for(j=0;j<16;j++)
  47.                                                 {
  48.                                                         write_1602dat(ResetOK[j]);          //密码修改成功,显示
  49.                                                 }

  50.                                                 TwoAlam();                                //操作成功提示
  51.                                                  WrToROM(TempPassword,0,6);                //将新密码写入24C02存储
  52.                                                 ReInputEn=0;
  53.                                         }
  54.                                         ReInputCont=0;
  55.                                         CorrectCont=0;
  56.                                 }
  57.                                 else                                          //输入一次密码时
  58.                                 {
  59.                                         OneAlam();
  60.                                         //DisplayListChar(0, 1, again);                 //显示再次输入一次
  61.                                         write_1602com(er);
  62.                                         for(j=0;j<16;j++)
  63.                                         {
  64.                                                 write_1602dat(again[j]);                        //显示再输入一次
  65.                                         }                                       
  66.                                         for(i=0;i<6;i++)
  67.                                         {
  68.                                                 TempPassword[i]=InputData[i];                //将第一次输入的数据暂存起来                                               
  69.                                         }
  70.                                 }

  71.                         N=0;                                                //输入数据位数计数器清零
  72.                    }
  73.             }
  74.         }
  75. }
  76. //=======================输入密码错误超过三过,报警并锁死键盘======================
  77. void Alam_KeyUnable(void)
  78. {
  79.         P1=0x00;
  80.         {
  81.                 ALAM=~ALAM;                                 //蜂鸣器一直闪烁鸣响
  82.                 Delay5Ms();
  83.         }
  84. }
  85. //=======================取消所有操作============================================
  86. void Cancel(void)
  87. {      
  88.         unsigned char i;
  89.         unsigned char j;
  90.         //DisplayListChar(0, 1, start_line);
  91.         write_1602com(er);
  92.         for(j=0;j<16;j++)
  93.         {
  94.                 write_1602dat(start_line[j]);          //显示开机输入密码界面
  95.         }
  96.         TwoAlam();                                //提示音
  97.         for(i=0;i<6;i++)
  98.         {
  99.                 InputData[i]=0;                //将输入密码清零
  100.         }
  101.         KEY=1;                                        //关闭锁
  102.         ALAM=1;                                        //报警关
  103.         pass=0;                                        //密码正确标志清零
  104.         ReInputEn=0;                        //重置输入充许标志清零
  105.         ErrorCont=0;                        //密码错误输入次数清零
  106.         CorrectCont=0;                        //密码正确输入次数清零
  107.         ReInputCont=0;                        //重置密码输入次数清零
  108.         s3_keydown=0;
  109.         key_disable=0;                        //锁定键盘标志清零
  110.         N=0;                                        //输入位数计数器清零
  111. }

  112. //==========================确认键,并通过相应标志位执行相应功能===============================
  113. void Ensure(void)
  114. {      
  115.         unsigned char i,j;
  116.         RdFromROM(CurrentPassword,0,6);                                         //从24C02里读出存储密码
  117.     if(N==6)
  118.         {
  119.             if(ReInputEn==0)                                                        //重置密码功能未开启
  120.                 {
  121.                         for(i=0;i<6;)
  122.                            {                                       
  123.                                 if(CurrentPassword[i]==InputData[i])        //判断输入密码和24c02中的密码是否相同
  124.                                 {
  125.                                         i++;                                                                //相同一位 i就+1
  126.                                 }
  127.                                 else                                                                         //如果有密码不同
  128.                                 {                                                                              
  129.                                         ErrorCont++;                                                //错误次数++
  130.                                         if(ErrorCont==3)                        //错误输入计数达三次时,报警并锁定键盘
  131.                                         {
  132.                                                 write_1602com(er);
  133.                                                 for(i=0;i<16;i++)
  134.                                                 {
  135.                                                         write_1602dat(Error[i]);      
  136.                                                 }
  137.                                                 do
  138.                                                 Alam_KeyUnable();
  139.                                                 while(1);
  140.                                         }
  141.                                         else                                         //错误次数小于3次时,锁死键盘3秒,然后重新可以输入
  142.                                         {
  143.                                                 TR0=1;                                //开启定时
  144.                                                 key_disable=1;                        //锁定键盘
  145.                                                 pass=0;                                        //pass位清零
  146.                                                 break;                                        //跳出
  147.                                         }
  148.                                 }
  149.                         }

  150.                         if(i==6)                                         //密码输入对时
  151.                         {
  152.                                 if((InputData[0]==adminpassword[0])&&(InputData[1]==adminpassword[1])&&(InputData[2]==adminpassword[2])&&(InputData[3]==adminpassword[3])&&(InputData[4]==adminpassword[4])&&(InputData[5]==adminpassword[5]))
  153.                                    {
  154.                                         WrToROM(initpassword,0,6);                                 //强制将初始密码写入24C02存储
  155.                                         write_1602com(er);
  156.                                         for(j=0;j<16;j++)
  157.                                         {
  158.                                                 write_1602dat(initword[j]);                                //显示初始化密码
  159.                                         }
  160.                                         TwoAlam();                                                                        //成功提示音
  161.                                         Delay400Ms();                                                                //延时400ms
  162.                                         TwoAlam();                                                                        //成功提示音
  163.                                         N=0;                                                                                //输入位数计数器清零
  164.                                 }
  165.                                 else
  166.                                 {
  167.                                         CorrectCont++;                                        //输入正确变量++
  168.                                         if(CorrectCont==1)                                //正确输入计数,当只有一次正确输入时,开锁
  169.                                         {
  170.                                                 //DisplayListChar(0,1,LockOpen);
  171.                                                 write_1602com(er);
  172.                                                 for(j=0;j<16;j++)
  173.                                                 {
  174.                                                         write_1602dat(LockOpen[j]);                  //显示open开锁画面
  175.                                                 }
  176.                                                 TwoAlam();                        //操作成功提示音
  177.                                                 KEY=0;                                                                                        //开锁
  178.                                                 pass=1;                                                                                        //置正确标志位
  179.                                                 TR0=1;                                                                                        //开启定时
  180.                                                 for(j=0;j<6;j++)                                                                //将输入清除
  181.                                                 {
  182.                                                         InputData[i]=0;                                                                //开锁后将输入位清零
  183.                                                 }
  184.                                         }      
  185.                                         else                                                                                                //当两次正确输入时,开启重置密码功能
  186.                                         {
  187.                                                 write_1602com(er);
  188.                                                 for(j=0;j<16;j++)
  189.                                                 {
  190.                                                         write_1602dat(SetNew[j]);                                        //显示重置密码界面
  191.                                                 }
  192.                                                 TwoAlam();                                                                            //操作成功提示
  193.                                                 ReInputEn=1;                                                                        //允许重置密码输入
  194.                                                 CorrectCont=0;                                                                        //正确计数器清零
  195.                                         }
  196.                                 }
  197.                           }
  198.       
  199.                         else                        //=========================当第一次使用或忘记密码时可以用131420对其密码初始化============
  200.                         {
  201.                                 if((InputData[0]==adminpassword[0])&&(InputData[1]==adminpassword[1])&&(InputData[2]==adminpassword[2])&&(InputData[3]==adminpassword[3])&&(InputData[4]==adminpassword[4])&&(InputData[5]==adminpassword[5]))
  202.                                    {
  203.                                         WrToROM(initpassword,0,6);                                 //强制将初始密码写入24C02存储
  204.                                         write_1602com(er);
  205.                                         for(j=0;j<16;j++)
  206.                                         {
  207.                                                 write_1602dat(initword[j]);                                //显示初始化密码
  208.                                         }
  209.                                         TwoAlam();                                                                        //成功提示音
  210.                                         Delay400Ms();                                                                //延时400ms
  211.                                         TwoAlam();                                                                        //成功提示音
  212.                                         N=0;                                                                                //输入位数计数器清零
  213.                                 }
  214.                                 else                                                                                        //密码输入错误
  215.                                 {
  216.                                         write_1602com(er);
  217.                                         for(j=0;j<16;j++)
  218.                                         {
  219.                                                 write_1602dat(Error[j]);                                 //显示错误信息
  220.                                         }
  221.                                         ThreeAlam();                                                                                //错误提示音
  222.                                         pass=0;      
  223.                                 }
  224.                         }
  225.                 }

  226.                 else                                                                                        //当已经开启重置密码功能时,而按下开锁键,
  227.                 {
  228.                         //DisplayListChar(0,1,Er_try);
  229.                         write_1602com(er);
  230.                         for(j=0;j<16;j++)
  231.                         {
  232.                                 write_1602dat(Er_try[j]);                          //错误,请重新输入
  233.                         }
  234.                         ThreeAlam();                                                          //错误提示音
  235.                 }
  236.         }

  237.         else                                   //密码没有输入到6位时,按下确认键时
  238.         {
  239.                 //DisplayListChar(0,1,Error);
  240.                 write_1602com(er);
  241.                 for(j=0;j<16;j++)
  242.                 {
  243.                         write_1602dat(Error[j]);                 //显示错误
  244.                 }

  245.                 ThreeAlam();                                                                                //错误提示音
  246.                 pass=0;      
  247.         }
  248.       
  249.         N=0;                                                                                                        //将输入数据计数器清零,为下一次输入作准备
  250. }


  251. //==============================主函数===============================
  252. void main(void)
  253. {
  254.         unsigned char KEY,NUM;
  255.         unsigned char i,j;
  256.         P1=0xFF;                                    //P1口复位
  257.         TMOD=0x11;                                   //定义工作方式
  258.         TL0=0xB0;
  259.         TH0=0x3C;                                   //定时器赋初值
  260.         EA=1;                                           //打开中断总开关
  261.         ET0=1;                                           //打开中断允许开关
  262.         TR0=0;                                           //打开定时器开关
  263.         Delay400Ms();         //启动等待,等LCM讲入工作状态
  264.         lcd_init();         //LCD初始化
  265.         write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
  266.         for(i=0;i<16;i++)
  267.         {
  268.                 write_1602dat(name[i]);//向液晶屏写开机画面
  269.         }
  270.         write_1602com(er);
  271.         for(i=0;i<16;i++)
  272.         {
  273.                 write_1602dat(start_line[i]);//写输入密码等待界面
  274.         }
  275.         write_1602com(er+9);        //设置光标位置
  276.         write_1602com(0x0f);        //设置光标为闪烁
  277.         Delay5Ms(); //延时片刻(可不要)

  278.         N=0;                                                                                                                //初始化数据输入位数
  279.         while(1)                 //进入循环
  280.         {
  281.                 if(key_disable==1)                                                //锁定键盘标志为1时
  282.                         Alam_KeyUnable();                                        //报警键盘锁
  283.                 else
  284.                         ALAM=1;                                                                //关报警

  285.                 KEY=keynum();                                                        //读按键的位置码
  286.                 if(KEY!=0)                                                                //当有按键按下时
  287.                 {      
  288.                         if(key_disable==1)                                        //锁定键盘标志为1时
  289.                         {
  290.                                 second=0;                                                //秒清零
  291.                         }
  292.                         else                                                                //没有锁定键盘时
  293.                         {
  294.                                 NUM=coding(KEY);                                //根据按键的位置将其编码,编码值赋值给NUM
  295.                                 {
  296.                                         switch(NUM)                                        //判断按键值
  297.                                         {
  298.                                                 case ('A'):         ;                                         break;
  299.                                                 case ('B'):                ;                                     break;
  300.                                                 case ('C'):
  301.                                                                         write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
  302.                                                                         for(i=0;i<16;i++)
  303.                                                                         {
  304.                                                                                 write_1602dat(name[i]);//向液晶屏写开机画面
  305.                                                                         }
  306.                                                                         if(N>=1) N--;        OneAlam();                                                                //按键提示音                                               
  307.                                                                         //DisplayOneChar(6+N,1,'*');
  308.                                                                         for(j=N;j<16;j++)
  309.                                                                         {
  310.                                                                                 write_1602com(er+6+j);
  311.                                                                                 write_1602dat(' ');
  312.                                                                         }
  313.                                                                         for(j=0;j<N;j++)
  314.                                                                         {
  315.                                                                                 write_1602com(er+6+j);                                //显示位数随输入增加而增加
  316.                                                                                 write_1602dat('*');                                        //但不显示实际数字,用*代替
  317.                                                                         }  
  318.                                                                         InputData[N]=N+4;
  319.                                                                         break;                //ABC是无定义按键
  320.                                                 case ('D'): ResetPassword();                break;      //重新设置密码
  321.                                                 case ('*'): Cancel();                                break;      //取消当前输入
  322.                                                 case ('#'): Ensure();                                 break;           //确认键,
  323.                                                 default:                                                                                 //如果不是功能键按下时,就是数字键按下
  324.                                                 {      
  325.                                                         //DisplayListChar(0,1,Input);
  326.                                                         if(N<6)                                                           //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
  327.                                                         {
  328.                                                                 write_1602com(er);
  329.                                                                 for(i=0;i<16;i++)
  330.                                                                 {
  331.                                                                         write_1602dat(Input[i]);                                //显示输入画面
  332.                                                                 }
  333.                                                                 OneAlam();                                                                //按键提示音      
  334.                                                                  for(j=0;j<=N;j++)
  335.                                                                 {
  336.                                                                         write_1602com(er+6+j);                                //显示位数随输入增加而增加
  337.                                                                         write_1602dat('*');                                        //但不显示实际数字,用*代替
  338.                                                                 }
  339.                                                                 InputData[N]=NUM;                                                //将数字键的码赋值给InputData[]数组暂存
  340.                                                                 N++;                                                                        //密码位数加
  341.                                                         }
  342.                                                         else                                                                                //输入数据位数大于6后,忽略输入
  343.                                                         {
  344.                                                                 N=6;                                                                        //密码输入大于6位时,不接受输入
  345.                                                                  break;
  346.                                                         }
  347.                                                 }
  348.                                         }
  349.                                 }
  350.                         }
  351.                  }
  352.         }
  353. }

  354. //*********************************中断服务函数**************************************
  355. void  time0_int(void) interrupt 1                    //定时器T0
  356. {
  357.         TL0=0xB0;
  358.         TH0=0x3C;                  //定时器重新赋初值
  359.         //TR0=1;
  360.         countt0++;                           //计时变量加,加1次时50ms
  361.           if(countt0==20)                   //加到20次就是1s
  362.            {
  363.                 countt0=0;                   //变量清零
  364.                 second++;                   //秒加
  365.                 if(pass==1)                   //开锁状态时
  366.                 {
  367.                         if(second==1)                        //秒加到1s时
  368.                         {
  369.                                 TR0=0;                                //关定时器
  370.                                 TL0=0xB0;
  371.                                 TH0=0x3C;                        //再次赋初值
  372.                                 second=0;                        //秒清零
  373.                         }
  374.                 }
  375.                 else                                                //不在开锁状态时
  376.                 {
  377.                         if(second==3)                        //秒加到3时
  378.                         {
  379.                                 TR0=0;                                //关闭定时器
  380.                                 second=0;                        //秒清零
  381.                                 key_disable=0;                //锁定键盘清零
  382.                                 s3_keydown=0;      
  383.                                 TL0=0xB0;
  384.                                 TH0=0x3C;                        //重新赋初值
  385.                         }
  386.                         else
  387.                             TR0=1;                                //打开定时器
  388.                 }
  389.                        
  390.            }
  391. }
复制代码

回复

使用道具 举报

ID:76027 发表于 2024-5-15 20:49 | 显示全部楼层
已搞定,发现论坛上有的例程不知都被谁删掉了关键的语句。既然例程发上来了,为什么要删关键语句呢?这个二个地方加上标记红色的字符就可以修改密码:
     if(i==6)
                                        {
                                                //DisplayListChar(0,1,ResetOK);
                                                write_1602com(er);
                                                for(j=0;j<16;j++)
                                                {
                                                        write_1602dat(ResetOK[j]);          //密码修改成功,显示
                                                }

                                                TwoAlam();                                //操作成功提示
CurrentPassword[6] = TempPassword[6];
                                                 WrToROM(TempPassword,0,6);                //将新密码写入24C02存储
                                                ReInputEn=0;
                                        }
                                        ReInputCont=0;
                                        CorrectCont=0;
                                }



  else                        //=========================当第一次使用或忘记密码时可以用131420对其密码初始化============
                        {
                                if((InputData[0]==adminpassword[0])&&(InputData[1]==adminpassword[1])&&(InputData[2]==adminpassword[2])&&(InputData[3]==adminpassword[3])&&(InputData[4]==adminpassword[4])&&(InputData[5]==adminpassword[5]))
                                   {
CurrentPassword[6] = initpassword[6];
                                        WrToROM(initpassword,0,6);                                 //强制将初始密码写入24C02存储
                                        write_1602com(er);
                                        for(j=0;j<16;j++)
                                        {
                                                write_1602dat(initword[j]);                                //显示初始化密码

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:161164 发表于 2024-5-16 09:08 | 显示全部楼层
源代码是6位密码,用6位数组储存
CurrentPassword[6] 和 initpassword[6] 是第7位
数组溢出了
回复

使用道具 举报

ID:76027 发表于 2024-5-16 11:28 | 显示全部楼层
数组0-5,不就是6位吗?
回复

使用道具 举报

ID:161164 发表于 2024-5-16 16:35 | 显示全部楼层
bd5fna 发表于 2024-5-16 11:28
数组0-5,不就是6位吗?

那你新加CurrentPassword[6] = initpassword[6] 干嘛?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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