首页 > 编程知识 正文

数字密码锁怎么改密码,数字逻辑与数字系统设计答案张少敏

时间:2023-05-05 10:21:56 阅读:117069 作者:2916

哈佛大学2020数字逻辑大作业

1 .设计要求1.1主要设计要求(1)设计解锁密码不少于4位的密钥。

)2)解锁按钮开关)可设置8位以上,其中只有4位有效,其余位为虚数)输入码与设置的密码相等时,启动解锁控制电路,解锁状态用绿灯亮、红灯灭显示。

)3)如果按下第一个按钮后5秒钟内未解除锁定,电路将自动复位并发出警报信号。 同时,解除锁定的情况用绿灯熄灭,用红灯点亮。

1.2附加功能(1)可以通过设置密码并在解锁状态下设置密码按钮SP来设置密码。

) 5秒计时采用倒计时(即5s计时到0 )的方式,将秒数显示在开发板的7级数字代码上。 五秒后发出警报。

)3)可以清除密码输入,重新输入密码(不中止计时器)。

)4)设置密码和输入密码时,输入的密码全部显示在开发板的7个代码管中。

)5)密码输入错误、密码设置成功、密码输入成功后,对应提示会点亮。

2 .工作原理及系统框图2.1工作原理基于系统功能分析,整个系统可分为以下四个主要功能模块:

(1)编码模块)将输入的4位密码分别转换为8421-BCD码;

(2)存储模块)设置密码后,保存密码;

(3)比较模块)将后续输入的密码与保存的密码进行比较;

)4)计时模块)主要体现5秒倒计时的功能。

首先在输入端输入密码,然后在编码模块中将十进制密码转换为8421-BCD码并保存。 如果是设计密码的状态,就直接保存密码。 否则,输入4位密码后调用比较模块,将输入的密码与以前保存的密码进行比较。 输入的密码与设定的密码相等时,点亮为绿色; 否则,表示密码输入错误的指示灯会闪烁。 另外,在读取输入的第1位密码的瞬间,计时模块启动,开始5s倒计时。 如果在倒计时过程中解锁成功,立即停止计时器。 倒计时结束后仍未解除锁定时,密码锁定变为锁定状态,警告灯点亮。

2.2系统框图系统结构框图如下图所示。

3 .各部分模块的具体功能和设计思路3.1编码模块编码模块的核心功能是将输入的十进制数(0(7)编码为三位二进制数,功能类似于一个8-3编码器,其主要作用是为其他模块提供数据编码模块的输入和输出均在高电平下有效。

3.2存储模块通过编码模块将输入的十进制数字转换为二进制数字。 很明显,必须输入四位密码(即四个十进制),因此必须保存以下四个三位二进制: 我们想用4个3位寄存器分别存储这4个3位二进制数。 但是,4位的密码是按顺序输入的。 也就是说,4个寄存器依次动作,一次只能动作1个寄存器。

这里的顺序存储功能可以通过4位计数器和2-4解码器的组合来实现。 计数器选择各位,从1-4位开始计数。 为了知道输入了几个密码并依次正确存储,将计数器的时钟脉冲设定为按下密码输入端子时发生的上升沿,驱动计数器从00到11。 此外,通过将计数器的输出端子与解码器的输入端子连接,并将解码器的输出端子分别与4个寄存器的使能端子连接,从而完全实现分别使能4个寄存器并依次存储的功能。

另外,为了在每次按下密码输入端子时产生脉冲,可以通过或门实现。 最初密码输入端子为低电平,如果有一个高电平输入,则输出的时钟信号为高电平,计数器向下计数一个。

此外,为了方便用户设置和输入密码,每次用户输入密码时,无论是设置密码还是尝试解锁密码,提示都会闪烁,表示输入成功。 同时,用户输入的密码通过开发板上的七条代码管道显示,方便用户操作。

3.3比较模块比较模块的中心工作是确定输入的密码是否与存储模块中存储的密码相同。 为了实现比较功能,设计了4个3位数值比较器,当前输入的3位2进制数与以前保存的数均相等时,输出1 (高电平)。 因此,如果各比较器的输出端为1 (表示数值相等),则密码正确。 用与门连接4个输出端,与门输出1时绿灯点亮。 每次输入密码时都会产生脉冲,触发比较器的动作。 依次输入四个密码后,密码锁定将打开。

如果密码正确,绿灯点亮,表示解锁成功。 与此同时,计时器停止计数,其他所有灯熄灭。 另外,如果输入的4位密码错误,指示灯将闪烁并显示信息,计时器模块不会停止动作。

3.4计时模块计时模块主要包括分频器、计数器和显示器,可准确通过7段数码管显示秒数,且计时5s后可报警(alarm警示灯点亮)、亮红灯。 此时,将进入复位状态(清除输入,保存设定的密码),即使输入正确的密码也无法点亮绿色。

这里的计时5s可以通过计数器和分频器的组合来实现。 因为开发板的时钟频率为100Mhz,所以首先分频100M,计数器每计数一次就表示1s。 此外,在多解码器中显示与7段数码管对应的秒数。 如果输入0~7的数字之一,即开始输入密码,则开始倒计时5秒,此时复位信号is_locked=0(低电平),其他模块正常动作。 5s倒计时结束后,将is_locked设置为1 (高电平)。 也就是说,变为锁定状态,警告灯点亮。

4 .调试过程4.1计时器调试计时器的主要功能是5s倒计时,将秒数显示在7段数字代码中。 倒计时的功能其实比较简单,只要调整分频参数就可以实现。 调试最需要的其实是时机

器的启动和终止,因为尽管计时器是一个相对独立的模块,它的开始和停止很大程度上受到输入密码的控制。
我们规定,在设置密码的状态下,计时器不会启动;在尝试解锁时,输入第一位密码后,计时器启动;输入密码正确时,计时器中止;倒计时结束后,计时器中止,如不手动复位,则计时器不再启动。
上述功能我们是通过向计时器(timer)模块传递一个start参数进行实现的。首先初始化start<=0。在任何时候,一旦sp== 1(即进入设置密码状态),start保持为0;而一旦密码锁已经上锁,尝试输入密码时,更改start<=1;如果倒计时未停止且解锁成功,便立刻将start赋值为0,停止计时。这三种情况都比较好实现,相对复杂的是最后一种情况,即倒计时结束后,计时器需要立刻中止。因为start是传入timer模块的参数,所以在模块内部是不能给start赋值的,正是这一点造成了这种情况的复杂性。不过由于计时器倒计时结束alarm便会变成高电平,我们可以在主模块内部对alarm的值进行判断,一旦alarm==1,则start<=1。

4.2 设置及输入密码的调试

我最初的设想是只要pw(输入的密码)值改变,并且是有效值,就把输入转为二进制后保存下来。但是这样做存在一个致命的问题——对于一个reg类型的变量,verilog是不允许它在不同的两个always语句块中被赋值的,比如说我设置了一个clr按钮,一旦按下就清空当前输入的密码,那么清空操作触发的信号其实是posedge clr,这个操作改变了暂存密码的几个寄存器的值;而在always @(pw)语句块中,肯定也需要修改这几个寄存器的值,这就产生了矛盾。而如果将这两个always语句块合并,又与预期的功能不符,所以这个设想被否定了。
我在最后的代码里采用的想法是将这几个模块的处理统一放在一个always @(div_clk)语句块中,在语句块里检测sp,clr是否按下,pw是否有效等等。相对于之前的设想,这里对密码输入、clr操作等的检测的灵敏度一定程度上都下降了,但却能保证所有功能的正常实现。这里div_clk是对系统时钟的一个分频,这里分频的目的是便于用户输入密码——如果时钟频率过高,系统可能会一次读入多个密码;而如果频率过低,输入密码、clr、sp操作的效率就会下降。而只要分频合适,就能够兼顾上述功能的实现。以下是分频以及clr操作的部分代码。

4.3 七段数码管显示的调试

七段数码管在开发板的左上方,一共有8组数码管。下图是七段数码管的实物图。

但是在这8组数码管下方只标出了两组接口(图中较大的矩形框),这表明一次最多使用两个数码管。另外,在调试中我发现如果只对这两组接口进行赋值,七段数码管是不会有任何显示的,这就类似于数码管没有使能。经过更仔细的观察,我发现在每个七段数码管上方都有一个对应的接口(图中较小的蓝色矩形框),可以把这个看做数码管的使能端,只有在对应接口输入高电平数码管才能正常工作。

4.4 各类指示灯的调试

整个系统里有6个指示灯——alarm(警示灯)、red(红灯)、green(绿灯)、work(输入有效)、sp_success(设置密码成功)、fail(输入密码错误)。这些指示灯的设置一方面是便于用户使用,另一方面也是便于调试。
指示灯的调试其实是对不同状态的调试,指示灯不同代表密码锁进入了不同的状态。以下是密码锁的几个主要状态以及对应指示灯的情况:
(1)复位状态:密码锁启动后的状态——只有红灯亮;
(2)设置或输入密码状态:每输入一个有效密码——work灯闪烁一次;
(3)设置密码成功状态:设置密码状态下连续读入4位有效密码——sp_success灯闪烁一次;
(4)输入密码错误状态:尝试解锁时输入的4位密码错误——fail灯闪烁一次;
(5)解锁成功状态——只有绿灯亮;
(6)锁死状态:倒计时结束——alarm灯亮。
在调试过程中,经常出现的问题是在控制相应灯亮起的同时会忽略关闭其他指示灯,这会造成很多指示灯同时亮起,导致对状态辨别的困难。例如,一旦输入密码正确,便会进入解锁状态,绿灯亮起,但如果忘记对其他指示灯操作,很有可能红灯也是亮起状态,这就产生了一个没有规定过的状态。如果这时又按下了sp按钮,绿灯就必须立马熄灭,因为进入了设置密码状态。下面这段代码展示的是在解锁后对指示灯的配置。

5. 设计结论

我设计的电子密码锁有8个数字输入端,能存储4位密码,可以设置、修改密码,能够用绿灯亮表示密码输入正确,警示灯亮表示锁死。除了基本的功能外,我设计的电子密码锁还加入了一些对用户进行提示的功能。例如,倒计时和输入的密码均可以通过七段数码管显示出来,用户可以时刻了解到剩余的开锁时间、输入的密码;为了防止用户误输了密码,我还增加了清空密码输入的clr按钮,一旦按下就会清空密码输入;当设置密码成功、尝试输入密码错误时均会有相应指示灯亮起,以提示用户。
在现有基础上,密码锁还可以实现更多的功能。比如增加密码的位数,又比如在设置密码时也可以清空输入,这些都是密码锁可以优化、改进的地方。

6. 设计心得与总结

(1)模块化
将整个系统划分成若干子模块是非常重要的。模块化的过程是对整个问题分析、理解的过程,也有助于理清整个问题的实现思路。尽管我最后的代码并没有完全依照模块的划分去实现,但是总的思路偏差不大。除此之外,模块化还有一个好处在于如果想添加新的功能,只需要在相应模块里修改即可,而无需考虑整个代码。
(2)加注释
在编写一个较为复杂的工程时,及时地添加必要的注释是很重要的。写注释不仅仅是为了让别人看懂你的代码,更重要的是为自己理清思路,也便于后续的修改。对我而言,我不是很擅长变量命名,所以我在每个变量后面都加上了注释,如图所示。

这样一来,即使我一时忘记了某个变量的含义,也可以通过查看注释很快回想起来。
而在主程序中,也可以在if语句、case语句后加上注释,标明某段代码的功能。
(3)仿真文件
仿真文件可以帮助我验证某段代码的正确性,但一旦代码过多、输入输出变量个数过多,编写仿真文件反而成了一件麻烦的事情。我采取的方法是只针对子模块编写仿真程序,而不对整个工程编写仿真程序,因为那样做不仅费时费力,而且一旦某个变量出错还难以发现。
仿真文件测试通过也不能完全保证代码的正确性。有的问题只有把程序烧到板子上的时候才能发现。比如七段数码管的问题,如果只看仿真波形图的话,不会有一点问题,但是在板子上一测试就会发现数码管是不亮的,这时候才会发现问题所在。在板子上进行测试的另一个好处就是直观,也更容易发现一些隐藏的问题。比如我的密码锁共有6个指示灯,如果只看仿真波形图,很不直观,也很难发现问题,而在板子上一测试就会发现有些指示灯没控制好。

总结

这次的大作业很好的锻炼了我独立完成整个工程的能力。我收获到的不仅是代码的编写、调试能力的提升,还有自信心的提升。
在代码的编写方面,我体会到了模块化、添加注释的重要性,其实这些都不会花费很多时间,但如果不去做的话就会给后续的调试带去很大的麻烦。而代码的调试也是很有讲究的,在我看来,编写仿真文件、看仿真波形是粗调,可以大致验证代码的正确性;验证通过后再将代码烧录到板子上细调,如果直接烧到板子上调理论上也可以,不过若代码错误较多,是不方便定位错误的。
在自信心方面,这次的大作业对我的自信心是一次很大的提升。刚看到这道题目的时候,我是没有什么思路的。但经过细细分析,将问题逐渐分解,编写子模块的代码,组合代码等一系列过程后,我不但基本上完成了整个电子密码锁程序的编写,而且很有成就感,对于解决类似工程问题的信心增加了。

参考文献

[1] 粗犷的水池,wsdws.基于FPGA的电子密码锁系统的设计[J].智能计算机与应用,2019(02): 187-188+192.
[2] 熊军洲. 基于FPGA的电子密码锁控制电路设计[J].石家庄职业技术学院学报,2018(06): 11-15.
[3] hhdyz.关于FPGA的电子密码锁系统的设计[J].科学技术创新,2019(26):89-90.
[4] 康浩,野性的小丸子,王建国,wsddx,zydtn.基于FPGA的智能电子密码锁的设计[J].湖北理工学院学报,2014(03):45-49.
[5] yydxbw.电子密码锁控制电路设计[J].黑龙江科技信息,2017(15):38.

附录 附录一:总体设计图

附录二:各模块仿真截图

以下为各个模块的仿真结果截图。



附录三:组员所做工作说明

所有工作均由本人独立完成。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。