597329015 发表于 2023-5-27 21:20 首先感谢你的回答。 你的逻辑清晰,给我提供了一定的新思路。以你的效果灯必然是固定顺序亮起的,按键排列是随机的,就是已经设置好乱序键盘再来输入密码,像苹果手机解锁界面,但是键盘是乱序的,上面一排灯是用来提示密码总共位数和已输入位数,因此是必然一盏盏亮起表示依次被填满,与我所设计的不同。 此外密码输入次数是不受限制的,严格来讲这不是密码锁,只是一个训练短时记忆的小游戏。 如果可以,我想再问一个问题:灯和按键已经按顺序集成在了电路板上,不可再调序,如何按下按键亮起固定随机对应的灯? |
wulin 发表于 2023-5-27 17:20 八个按键八个灯,按键就是正常数字键盘类排序,灯是从上到下排成一列,解锁顺序从上到下,不一定从第一盏灯开始,但是每下一盏得在前一盏亮起位置的下面。 |
那是 几个按键 几个灯 |
画逻辑框图 |
随机对应:首先,我们需要将LED灯和按键一一对应,并将它们的位置随机排列。在单片机中定义一个变量表示当前亮起的灯的位置,初始值为-1(即没有任何灯亮起),每按下一个按键,就将当前亮起的灯的位置加1。如果该位置大于等于最后一个灯的位置,说明密码正确,解锁成功。否则,所有灯都会熄灭,并重新开始输入密码。 按顺序正确亮起:为了确保按键与LED灯按顺序正确亮起,我们可以在按下按键后使用逻辑运算比较当前灯的位置和上一个亮起的灯的位置,如果当前灯的位置大于上一个亮起的灯的位置,则将当前灯的位置设置为上一个灯的位置加1。 使用计时器:为了避免机械化攻击或无限制地尝试密码,我们可以使用计时器在一定时间内限制密码输入的次数,如果超过了设置的次数,系统将锁定一段时间,防止不正常的尝试。 状态显示:我们可以使用LED灯来显示当前系统的状态,例如借助三个LED灯来表示解锁成功、解锁失败和输入密码中等状态,方便用户进行操作。 电源管理:在系统设计中需要考虑供电问题,可以使用电池等不间断电源以确保该系统的长期稳定运行。 以下是实例代码: #include <reg51.h> sbit key1 = P1^0; //按键引脚定义 sbit key2 = P1^1; sbit key3 = P1^2; sbit led1 = P2^0; //LED引脚定义 sbit led2 = P2^1; sbit led3 = P2^2; int current_led = -1; //当前亮起的灯位置 int last_led = -1; //上一个亮起的灯位置 void init() { key1 = 1; //按键初始化为高电平 key2 = 1; key3 = 1; led1 = 0; //LED初始化为低电平熄灭状态 led2 = 0; led3 = 0; } void delay(int t) { //延时函数 for(int i=0; i<t; i++) { for(int j=0; j<120; j++); } } void main() { init(); while(1) { if(!key1) { //按键1被按下 if(current_led == -1 || current_led == last_led + 1) { //密码正确 current_led++; last_led = current_led; switch(current_led) { //根据当前亮起的LED位置控制LED灯亮灭 case 0: led1 = 1; break; case 1: led2 = 1; break; case 2: led3 = 1; break; } if(current_led == 2) { //所有LED灯都亮起,解锁成功 delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } else { //密码错误 delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } if(!key2) { //按键2被按下 if(current_led == -1 || current_led == last_led + 1) { //密码正确 current_led++; last_led = current_led; switch(current_led) { case 0: led1 = 1; break; case 1: led2 = 1; break; case 2: led3 = 1; break; } if(current_led == 2) { delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } else { //密码错误 delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } if(!key3) { //按键3被按下 if(current_led == -1 || current_led == last_led + 1) { //密码正确 current_led++; last_led = current_led; switch(current_led) { case 0: led1 = 1; break; case 1: led2 = 1; break; case 2: led3 = 1; break; } if(current_led == 2) { delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } else { //密码错误 delay(500); led1 = 0; led2 = 0; led3 = 0; current_led = -1; last_led = -1; } } } } |
violet233 发表于 2023-5-27 15:48 《按键随机对应一个灯,按下按键亮起的灯的位置必须在前一个亮起的灯下面》怎么理解?几个按键几个灯?按键与灯的排列布局如何? |
本帖最后由 violet233 于 2023-5-28 11:09 编辑 主要就是我不熟悉指针,变量的关系,无法实现想要的逻辑效果,望各位大佬指点! 八个按键八个灯,按键就是正常数字键盘类排序,灯可以是从上到下排成一列,解锁顺序是从上到下一盏盏依次亮起,不一定从第一盏灯开始,但是每下一盏得在前一盏亮起位置的下面一位。按键随机对应灯,但是每次完整解锁过程都是对应同一盏灯,按该按键就对应亮这盏灯,直至解锁成功,进行下一次解锁按键和灯的顺序从新编排。 |