防试锁定-1
SUN的贴心提示
很意外吧,写完密码初始化和输入,就开始写防试锁定了😎,原因很简单,这是一个前置逻辑:锁定了之后就不能输入密码了!所以先判断是否锁定,再考虑能否输入密码!
还没完
防试锁定要和密码错误判断一起写,但是密码正确之后有很长逻辑链要走,而防试锁定在里面知作用只是简单的赋值———————为了防止喧宾夺主,密码正确之后的逻辑单独写,现在只能打个框架
逻辑流程图
为啥这么想?
- 锁定了之后就不能输入密码了!所以先判断是否锁定,再考虑能否输入密码!
- 锁定之后就要跳其他UI和逻辑,不再进密码输入逻辑了
- 我需要标记锁定这个状态
- 锁定逻辑单独整一个函数吧
- 分钟退位到秒要吧
- 计时中UI是一回事,计时是另一回事吧(前后端分离bushi)
- 配套UI显示要吧
- 循环反复减时长要吧
- 倒计时结束要退出循环吧
- 退出循环要改标志位吧(不然又锁了QAQ)
开码!
- 开始锁
void startLockCountdown() {
LCD_ShowString(1, 1, "Locked for 3min");
LCD_ShowString(2, 1, " :");
}
- 时间计算以及退位
while (lockTime > 0)
{
if (Sec > 0)
{
Sec--;
}
else
{
if (Min > 0)
{
Min--;
Sec = 59;
}
}
}
- 定义标记位和锁定时长
unsigned char lockFlag = 0; // 锁定状态标志
unsigned char lockTime = 180; // 锁定时间 3分钟 (180秒)
- 解锁标记位
lockFlag = 0; // 解除锁定
- 计时UI显示
SUN的能力问题
能力不够导致不会使用正常退位的方式计时,所以显示和真正的用于控制循环的计时是两个变量,符合新时代前后端分离的先进程序设计理念(bushi)
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; // 锁定期间跳过密码输入
}
// 扫按键,自己去前面找
}
}
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;
}
}
}