Skip to main content

防试锁定-1

SUN的贴心提示

很意外吧,写完密码初始化和输入,就开始写防试锁定了😎,原因很简单,这是一个前置逻辑:锁定了之后就不能输入密码了!所以先判断是否锁定,再考虑能否输入密码!

还没完

防试锁定要和密码错误判断一起写,但是密码正确之后有很长逻辑链要走,而防试锁定在里面知作用只是简单的赋值———————为了防止喧宾夺主,密码正确之后的逻辑单独写,现在只能打个框架

逻辑流程图

先思考,再展开流程图

进入锁定

计时以及计时显示逻辑

为啥这么想?

  • 锁定了之后就不能输入密码了!所以先判断是否锁定,再考虑能否输入密码!
  • 锁定之后就要跳其他UI和逻辑,不再进密码输入逻辑了
  • 我需要标记锁定这个状态
  • 锁定逻辑单独整一个函数吧
  • 分钟退位到秒要吧
  • 计时中UI是一回事,计时是另一回事吧(前后端分离bushi)
  • 配套UI显示要吧
  • 循环反复减时长要吧
  • 倒计时结束要退出循环吧
  • 退出循环要改标志位吧(不然又锁了QAQ)

开码!

  1. 开始锁
void startLockCountdown() {
LCD_ShowString(1, 1, "Locked for 3min");
LCD_ShowString(2, 1, " :");

}

  1. 时间计算以及退位
while (lockTime > 0)
{
if (Sec > 0)
{
Sec--;
}
else
{
if (Min > 0)
{
Min--;
Sec = 59;
}
}
}

  1. 定义标记位和锁定时长

unsigned char lockFlag = 0; // 锁定状态标志
unsigned char lockTime = 180; // 锁定时间 3分钟 (180秒)

  1. 解锁标记位

lockFlag = 0; // 解除锁定

  1. 计时UI显示
SUN的能力问题

能力不够导致不会使用正常退位的方式计时,所以显示和真正的用于控制循环的计时是两个变量,符合新时代前后端分离的先进程序设计理念(bushi)


unsigned char Min = 3, Sec = 0; // 3分钟倒计时

  1. 锁定逻辑摆在最前面
void main()
{
LCD_Init();
LCD_ShowString(1, 1, "PassWord:");
showPasswordFormat(6);

while(1)
{
// 如果处于锁定状态,执行锁定倒计时
if(lockFlag) {
startLockCountdown(); // 启动3分钟倒计时
continue; // 锁定期间跳过密码输入
}

// 扫按键,自己去前面找


}
}

lockCount的墓碑

这里本来有一个 unsigned int lockCount = 0;打算用来做密码尝试次数的UI显示,但是后面优化逻辑的时候呗删除了,他又不用退位,读loginAttempts就行了。特此醒目立碑纪念它给我带来的黄金赤石体验

组合逻辑

至此,组合逻辑


#include <REGX52.H>
#include "LCD1602.h"
#include "matrixkey.h"
#include "Buzzer.h"
#include "Delay.h"
#include <math.h> //引用一点库和已经抄好的库

unsigned char KeyNum;
unsigned int Password1 = 0, Password2 = 0, count = 0;
unsigned int secret1 = 11111;
unsigned int secret2 = 1; //具有SUN特色的sz密码存储逻辑
unsigned char lockFlag = 0; // 锁定状态标志
unsigned char lockTime = 180; // 锁定时间 3分钟 (180秒)
unsigned char Min = 3, Sec = 0; // 3分钟倒计时


void main()
{
LCD_Init();
LCD_ShowString(1, 1, "PassWord:");
showPasswordFormat(6);

while(1)
{
// 如果处于锁定状态,执行锁定倒计时
if(lockFlag) {
startLockCountdown(); // 启动3分钟倒计时
continue; // 锁定期间跳过密码输入
}

// 处理按键输入
KeyNum = Matrixkey();
if(KeyNum)
{
if(KeyNum <= 10) // 如果s1~s10按键按下,输入密码
{
if(count < 5)
{
Password1 *= 10; // 密码左移一位
Password1 += KeyNum % 10; // 获取一位密码
count++; // 计次
}
else if (count == 5)
{
Password2 = KeyNum % 10;
count++;
}
}
showPasswordFormat(6);
}

if(KeyNum == 11) // 确认键
{
// 参见————密码对了吗?
}

if(KeyNum == 12) // 退位
{
if(count > 0)
{
if(count <= 5)
{
Password1 /= 10;
}
else
{
Password2 = 0;
}
count--;
showPasswordFormat(6);
}
}


}
}


倒计时逻辑


// 锁定状态倒计时
void startLockCountdown() {
LCD_ShowString(1, 1, "Locked for 3min");
LCD_ShowString(2, 1, " :");
while (lockTime > 0)
{
LCD_ShowNum(2, 1, Min, 1); // 显示分钟
LCD_ShowNum(2, 3, Sec, 2); // 显示秒数

Delay(1000); // 每秒延迟一次

if (Sec > 0)
{
Sec--;
}
else
{
if (Min > 0)
{
Min--;
Sec = 59;
}
}

if (Min == 0 && Sec == 0)
{
lockFlag = 0; // 解除锁定
LCD_ShowString(2, 1, "Time up!"); // 显示倒计时结束
Delay(2000); // 显示 "Time up!" 2秒
LCD_ShowString(2, 1, "------ ");
LCD_ShowString(1, 1, "PassWord: "); // 恢复显示
break;
}
}
}