找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10871|回复: 16
收起左侧

我做的EDA密码锁仿真Quartus II课程设计报告

  [复制链接]
ID:215389 发表于 2017-6-28 15:55 | 显示全部楼层 |阅读模式
此程序目前只能仿真实现,稍作修改便可以做成实物。

EDA课程设计报告

课程设计名称:电子密码锁

院系:机械与电子信息工程系

专业:电子信息工程

班级:1430402

学号:20143*0228

姓名:吴*琴

指导老师:蔡*民


2017年6月
  • 实验目的:

利用基于所学EDA相关知识以Quartus II 软件设计一个具有较高安全性和较低成本的通用电子密码锁,其具体功能要求如下:

  • 密码输入:每按下一个数字键,就输入一个数值,并在显示器上的最左方显示‘*’号,输入第二个数值后,最左方显示两个‘*’号,直到输入完8位数值密码后,显示器上显示出8个‘*’号。输入完成8位数值密码后,输入的数值无效。
  • 密码清除:按下此键可以撤销前一次输入的密码。
  • 密码更改:在开锁状态下按下此键时会将目前的数字设定成新的密码,其它状态密码更改无效。
  • 解除电锁:按下此键会检查输入的密码是否正确,密码正确即开锁。
  • 警报:密码在连续三次输入错误之后,电子密码锁会发出警报。
  • 实验内容
  • 新建工程dianzimimasuo
  • 新建Verilog HDL File
选择菜单File,选择New选项,根据所使用的硬件描述语言类型选择相应的新建文件型(Verilog HDL File)。                           
  • 输入程序
  • 编译
  • 仿真

三.任务分析和设计方案

作为通用电子密码锁,主要由三个部分组成:数字密码输入电路,密码锁控制电路和密码显示电路。

各个模块电路的选取:

  • 数字密码输入电路采用4x4矩阵键盘。

(1)4x4矩阵键盘的工作原理:矩阵键盘又称为行列式键盘,它是由4条行线,4条列线组成的键盘,其原理如图1.1所示,在行线和列线的每个交叉点上,设置一个按键,按键的个数是4x4个,按键排列如图1.2所示。当按下某个按键后,为了辨别和读取键值信息,一般采用如下的方法:向X端口扫描输入一组只含一个0的4位数据,如1110,1101,1011,0111,如有按键按下,则Y口一定会输出对应的数据,因此,只要结合X,Y口的数据,就能判断按键的位置。

1.002.jpg

     图1.1  4x4矩阵键盘电路


图片详见51hei附件)


                                     图1.2按键排列

(2)4x4矩阵键盘检测程序:如下是用Verilog编写的4x4矩阵键盘键值扫描判断程序,键盘扫描程序由1个always模块构成,在always模块中先进行模4计数,在计数器的每个状态从FPGA内部送出一列扫描数据给键盘,然后读入经过去抖处理的4行数据,根据行,列数据,确定按下的是哪个键。

//按键模块

module scankey(clk,a,b,keyvalue);

input clk;                 //键盘扫描时钟信号

input [3:0]b;

output reg[3:0]a;                                          //输出扫描信号给键盘

output reg [3:0]keyvalue;

reg [1:0]q;

reg [3:0] qdb;//消抖后的b

reg [3:0]rxbuf;

always @( posedge clk) begin //按键消抖

rxbuf[0] <= b[0];

qdb[0] <= ~(rxbuf[0] & (~b[0]));

end

always @( posedge clk) begin //按键消抖

rxbuf[1] <= b[1];

qdb[1] <= ~(rxbuf[1] & (~b[1]));

end

always @( posedge clk) begin //按键消抖

rxbuf[2] <= b[2];

qdb[2] <= ~(rxbuf[2] & (~b[2]));

end

always @( posedge clk) begin //按键消抖

rxbuf[3] <= b[3];

qdb[3] <= ~(rxbuf[3] & (~b[3]));

end

always@(posedge clk)

begin q<=q+1;

case(q)                                                                      //给a口送出扫描数据

0:a<=4'b1110;

1:a<=4'b1101;

2:a<=4'b1011;

3:a<=4'b0111;

endcase

case({a,qdb})                                                                      //判断键值

8'b1110_0111:keyvalue<=4'b0000;              //key0

8'b1110_1011:keyvalue<=4'b0001;              //key1

8'b1110_1101:keyvalue<=4'b0010;

8'b1110_1110:keyvalue<=4'b0011;

8'b1101_0111:keyvalue<=4'b0100;

8'b1101_1011:keyvalue<=4'b0101;

8'b1101_1101:keyvalue<=4'b0110;

8'b1101_1110:keyvalue<=4'b0111;

8'b1011_0111:keyvalue<=4'b1000;

8'b1011_1011:keyvalue<=4'b1001;              //key9

8'b1011_1101:keyvalue<=4'b1010;              //keyA

8'b1011_1110:keyvalue<=4'b1011;

8'b0111_0111:keyvalue<=4'b1100;

8'b0111_1011:keyvalue<=4'b1101;

8'b0111_1101:keyvalue<=4'b1110;              //keyE

8'b0111_1110:keyvalue<=4'b1111;              //keyF

default:keyvalue=8'b1111_1111;

endcase

end

Endmodule

  • 密码显示电路采用8个七段数码管显示密码输入状态,绿色发光二极管指示锁的开闭状态,黄色发光二极管指示密码修改成功与否,红色发光二极管指示警报状态。
  • 密码锁控制电路采用EP4CE10F17C8芯片控制。

根据以上选定的输入设备和显示器件,并考虑到实现各项数字密码锁功能的具体要求,整个电子密码锁系统的总体组成框图如图1.3所示。

(1)密码锁输入电路包括时序产生电路,键盘扫描电路,键盘弹跳消除电路,键盘译码电路等几个小的功能电路。

(2)密码锁控制电路包括按键数据的缓冲存储电路,密码的清除,变更,存储,密码核对(数值比较电路),解锁电路(开/关门锁电路)等几个小的功能电路。

(3)七段数码管显示电路主要将待显示数据的BCD码转换成数码器的七段显示驱动编码。

(详见51hei附件)

   密码控制电路

显示电路

     七段数码管

图1.3数字电子密码锁系统总体框图

总体设计方案:

采用主,从两个状态机来完成8位电子密码锁设计。

主状态机用来完成waits(等待)状态,pass(开锁)状态,changing(改密)状态,alarm(警报)状态之间的切换。主状态机状态图如图2.1所示

(详见51hei附件)

图2.1主状态机

主状态机简要说明:复位键(Resetb)为0,进入等待(waits)状态;主现状态为等待状态且correct为1,主状态进入开锁(pass)状态;在开锁状态延时10s后,主状态回到等待状态;主现态为开锁状态且mimagaile为1,主状态进入改密(changing)状态;在改密状态延时10s后,主状态回到等待状态;主现态为等待状态且密码连续输入错误3次,主状态进入警报(alarm)状态;在警报状态延时1分钟后,主状态回到等待状态。

从状态机用于输入8位密码,程序如下:

always@(posedge clk or negedge resetb)

begin

      if(!resetb)

                            sub_state<=first;//从状态为first

                            else

                            sub_state<=next_sub_state;//从状态为下一个从状态

end

                            always@(cmd or cmd_t or sub_state)

begin

      if(cmd_t==0)//检测有按键按下

                            case(cmd)

                            cancel:begin //密码输入错误时,重复上一个状态

                                                        if(sub_state==first)

                                                        next_sub_state=first;

                                                        else

                                                        case(sub_state)

                                                        second:next_sub_state=first;

                                                        third: next_sub_state=second;

                                                        fourth:next_sub_state=third;

                                                        fifth:next_sub_state=fourth;

                                                        sixth:next_sub_state=fifth;

                                                        seventh:next_sub_state=sixth;

                                                        eighth:next_sub_state=seventh;

                                                        finish:next_sub_state=eighth;

                                                        endcase

end

//4个密码输完时,进行确认

enter:next_sub_state=first;

setmima:next_sub_state=first;

sure:next_sub_state=first;

//default为输入了某位密码,输入完自动将状态转入下一位

default:

                                          case(sub_state)

                                                                                    first:begin next_sub_state=second;dig=8'b00000001;end

                                                                                    second:begin next_sub_state=third;dig=8'b00000011;end

                                                                                    third:begin next_sub_state=fourth;dig=8'b00000111;end

                                                                                    fourth:begin next_sub_state=fifth;dig=8'b00001111;end

                                                                                    fifth:begin next_sub_state=sixth;dig=8'b00011111;end

                                                                                    sixth:begin next_sub_state=seventh;dig=8'b00111111;end

                                                                                    seventh:begin next_sub_state=eighth;dig=8'b01111111;end

                                                                                    eighth:begin next_sub_state=finish;dig=8'b11111111;end      //当输入完8位密码后状态保持不变,等待输入enter命令

                                                                                    finish:begin next_sub_state=finish;dig=8'b11111111;end

                                          endcase

endcase

else

next_sub_state=sub_state;

end

从状态机简要说明:按下清除键后从状态机状态回到前一个状态,按下数字键后从状态机为下一个状态(即输入下一位密码)

四.实验结果

功能验证:

  • cmd为输入命令用来代替按键验证功能,cmd=0000表示按键0,cmd=0001表示按键1,cmd=0010表示按键2,cmd=0011表示按键3,cmd=0100表示按键4,cmd=0101表示按键5,cmd=0110表示按键6,cmd=0111表示按键7,cmd=1000表示按键8,cmd=1001表示按键9,cmd=1010表示确认键,cmd=1011表示清除键,cmd=1101表示改密键。
  • dig用来控制8个共阳数码管的公共端(即可以控制8个数码管‘——’的亮灭来显示密码输入到第几位)。
  • passed输出高电平表示开锁状态。
  • resetmimaok输出高电平表示修改密码成功。
  • alarmed输出高电平表示警报状态。

1.065.jpg

图3.1总体功能仿真结果(包含开锁,改密,清除,警报,显示密码输入到第几位)

下面将总图按功能分解分析:

1.066.jpg 图3.2初始密码开锁功能

初始密码为11111111,如图3.2中40ns开始输入密码为11011111按下确认键(1010)后密码错误passed保持低电平(电子锁未打开),接着输入正确密码(11111111)按下确认键(1010)后密码正确passed输出高电平(电子锁打开)。

1.067.jpg

图3.3修改密码功能

如图3.3在passed为高(即开锁状态)输入8位数字后按下改密键(1101)密码被修改为11101111成功,resetmimaok输出高电平。接着输入初始密码11111111按下确认键(1010)passed保持低电平(电子锁未打开)之后再随便输入一个错误密码,如图3.3输入01111110按下确认键(1010)passed保持低电平(电子锁未打开),最后输入修改后的密码11101111按下确认键(1010)passed输出高电平(电子锁打开)。

1.068.jpg

图3.4输入大于8个数字时,前8位有效

如图3.4中800ns处输入密码111011111按下确认键(1010)后passed输出高电平(电子锁打开)说明第九位数字1无效。

1.069.jpg

图3.5三次连续输错密码后警报

如图3.5在950ns处开始连续输入错误三次密码后,alarmed输出高电平表示发出警报。

1.070.jpg

图3.6清除功能

如图3.6在1.31us处输入密码1110113后按下清除键(1011)接着输入11后,按下确认键(1010)passed输出高电平(电子锁打开)。

五.存在的问题及改进分析

  • 存在的问题:硬件电路该怎么做?如何把此设计做成实物?
  • 改进分析:数码管显示模块可以改为输入数字后显示输入的数字一秒钟后变为‘*’;可以增加一个管理员密码,管理员密码优先级高于普通密码,警报的解除只能靠输入管理员密码,输入管理员密码可以开锁和更改普通密码。

六.实验心得及意见

通过这次设计,使我对EDA产生了浓厚的兴趣。特别是当实现每个小功能成功时,心里特别开心。这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到的问题,反映出来我的许多不足之处,我以后要努力克服缺点。虽然此设计在Quartus II 软件上功能能够大体上得到验证,但是离做出实物还差很远。一直没有玩过实物开发板,根本就不知道进行硬件的连接,就连一个简单的程序都下载进开发板进行验证。总的来说,这次设计的密码锁还是比较成功的,在设计中遇到了很多问题,最后在同学和老师的辛勤的指导下外加上自己的努力,终于都得到了解决,因此很有成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的。

最后说一说我对本课程一些意见,该课程从开始做实验到最后的课程设计都一直是在电脑上进行仿真,没有在板子上跑过程序,我觉得老师应该在开发板给我们演示简单的程序,这样能够带动我们大多数人的兴趣,也能够便于我们更快上手做一些简单的实物,提高大家学习的积极性。


七.附录
程序:
  1. module dianzisuo(clk,resetb,cmd,cmd_t,alarmed,passed,resetmimaok,dig);
  2. input cmd_t;//输入命令控制信号
  3. input clk;  //输入时钟信号
  4. input resetb;  //输入复位信号
  5. input [3:0] cmd;//输入命令信号
  6. output reg [7:0]dig;//位选输出信号
  7. output alarmed; //输出警报信号
  8. output passed;  //输出通过信号
  9. output resetmimaok;  //输出密码修改成功信号
  10. reg alarmed;
  11. reg passed;
  12. reg resetmimaok;
  13. wire clk;
  14. wire resetb;
  15. wire [3:0]cmd;
  16. wire cmd_t;
  17. reg[22:0]CNT_R0;//clk1延时寄存器
  18. reg clk1;//clk为10ns时clk1为5ms周期脉冲                                
  19. reg [31:0]inputpassword;//输入值存放寄存器
  20. reg [31:0]PASSWORD=32'b0001_0001_0001_0001_0001_0001_0001_0001;//初始密码
  21. parameter zero=4'b0000,//0
  22.                          one=4'b0001,//1
  23.                          two=4'b0010,//2
  24.                          three=4'b0011,//3
  25.                          four=4'b0100,//4
  26.                          five=4'b0101,//5
  27.                          six=4'b0110,//6
  28.                          seven=4'b0111,//7
  29.                          eight=4'b1000,//8
  30.                          nine=4'b1001,//9
  31.                          enter=4'b1010,//确认键
  32.                          cancel=4'b1011,//清除一位键
  33.                          setmima=4'b1100,//
  34.                          sure=4'b1101;//修改密码键
  35. reg [3:0]main_state;//主现态
  36. reg [3:0]next_state;//主次态
  37. parameter waits=4'b0001,
  38.                          pass=4'b0010,
  39.                          alarm=4'b0100,
  40.                          changing=4'b1000;
  41. reg [3:0]sub_state;//从现态
  42. reg [3:0]next_sub_state;//从次态
  43. parameter first=4'b0000,
  44.                     second=4'b0001,
  45.                          third=4'b0010,
  46.                          fourth=4'b0100,
  47.                          fifth=4'b1000,
  48.                          sixth=4'b0011,
  49.                          seventh=4'b0101,
  50.                          eighth=4'b0110,
  51.                          finish=4'b0111;
  52. reg[7:0] pass_count;//通过计时寄存器
  53. reg[10:0] alarm_count;//警报计时寄存器
  54. reg[1:0] try_count;//尝试次数寄存器
  55. reg[7:0] mima_count;//改密计时寄存器
  56. reg error;
  57. reg correct;
  58. reg mimagaile;
  59. //clk为10ns时,clk1为5ms时钟
  60. always @(posedge clk)
  61. begin
  62. CNT_R0 <= CNT_R0 + 1'b1;
  63. if(CNT_R0 < 5000000)
  64. begin
  65. clk1 <= 1;
  66. end else
  67. begin
  68. clk1 <= 0;
  69. end
  70. end
  71. //主状态机部分
  72. always@(main_state or correct or error or try_count or pass_count or alarm_count or mimagaile)
  73. begin
  74. case(main_state)
  75. waits: if(correct==1)//由waits转换到pass的条件
  76.                 begin
  77.                 next_state=pass;
  78.                 end
  79.                 else if(error==1&&try_count==2)
  80.                 next_state=alarm;//由waits转换的alarm的条件
  81.                 else
  82.                 next_state=waits;
  83. pass: if(pass_count[7]==1)//由pass转换到waits的条件
  84.                 next_state=waits;
  85.                 else if(mimagaile==1)//由pass转换到changing的条件
  86.                 next_state=changing;
  87.                 else
  88.                 next_state=pass;
  89. changing:if(mima_count[7]==1)//由changing转换到waits的条件
  90.                         next_state=waits;
  91.                         else
  92.                         next_state=changing;
  93. alarm:if(alarm_count[10]==1)//由alarm转换到waits的条件
  94.                 next_state=waits;
  95.                 else
  96.                 next_state=alarm;
  97. default:next_state=waits;
  98. endcase
  99. end
  100. //alarm一段时间后,自动进入waits状态
  101. //alarm定时器
  102. always@(posedge clk1 or negedge resetb)
  103. begin
  104. if(!resetb)
  105. alarm_count<=0;
  106. else if(main_state==alarm)//alarm状态计时器alarm定时器加1
  107. alarm_count<=alarm_count+1;
  108. else
  109. alarm_count<=0;
  110. end
  111. //锁pass以后计数开始,当规定的时间到达后自动上锁,并进入waits状态
  112. //pass定时器
  113. always@(posedge clk1 or negedge resetb)
  114. begin
  115. if(!resetb)
  116. pass_count<=0;
  117. else if(main_state==pass) //pass状态计时器pass定时器加1
  118. pass_count<=pass_count+1;
  119. else
  120. pass_count<=0;
  121. end
  122. //changing以后计数开始,当规定的时间到达后自动上锁,并进入waits状态
  123. //changing定时器
  124. always@(posedge clk1 or negedge resetb)
  125. begin
  126. if(!resetb)
  127. mima_count<=0;
  128. else if(main_state==changing) //changing状态计时器mima_count定时器加1
  129. mima_count<=mima_count+1;
  130. else
  131. mima_count<=0;
  132. end
  133. //状态转换
  134. always@(posedge clk or negedge resetb)
  135. begin
  136.         if(!resetb)//如果按下复位键,则主状态为等待状态
  137.         main_state<=waits;
  138.         else                        //如果没按则进入下一个状态
  139.         main_state<=next_state;
  140. end
  141. //输出控制部分
  142. always@(posedge clk or negedge resetb)
  143. begin
  144.                 if(!resetb)//复位按下时,开锁输出和报警输出都为零
  145.                 begin
  146.                       passed<=0;
  147.                                 alarmed<=0;
  148.                                 resetmimaok<=0;
  149.                 end
  150.                 else if(main_state==pass)//当主机状态为pass时开锁
  151.                 begin
  152.                                 passed<=1;
  153.                                 alarmed<=0;
  154.                                 resetmimaok<=0;
  155.                 end
  156.                 else if(main_state==changing)//当主机状态为changing时,改密码
  157.                 begin
  158.                                 passed<=0;
  159.                                 alarmed<=0;
  160.                                 resetmimaok<=1;
  161.                 end
  162.                 else if(main_state==alarm)//当主机状态为alarm时,警报
  163.                 begin
  164.                                 passed<=0;
  165.                                 alarmed<=1;
  166.                                 resetmimaok<=0;
  167.                 end
  168. end
  169. //从状态机,用于输入8位密码
  170. always@(posedge clk or negedge resetb)
  171. begin
  172.       if(!resetb)
  173.                 sub_state<=first;//从状态为first
  174.                 else
  175.                 sub_state<=next_sub_state;//从状态为下一个从状态
  176. end
  177.                 always@(cmd or cmd_t or sub_state)
  178. begin
  179.       if(cmd_t==0)//检测有按键按下
  180.                 case(cmd)
  181.                 cancel:begin //密码输入错误时,重复上一个状态
  182.                                  if(sub_state==first)
  183.                                  next_sub_state=first;
  184.                                  else
  185.                                  case(sub_state)
  186.                                  second:next_sub_state=first;
  187.                                  third: next_sub_state=second;
  188.                                  fourth:next_sub_state=third;
  189.                                  fifth:next_sub_state=fourth;
  190.                                  sixth:next_sub_state=fifth;
  191.                                  seventh:next_sub_state=sixth;
  192.                                  eighth:next_sub_state=seventh;
  193.                                  finish:next_sub_state=eighth;
  194.                                  endcase
  195. end
  196. //4个密码输完时,进行确认
  197. enter:next_sub_state=first;
  198. setmima:next_sub_state=first;
  199. sure:next_sub_state=first;
  200. //default为输入了某位密码,输入完自动将状态转入下一位
  201. default:
  202.                         case(sub_state)
  203.                                                 first:begin next_sub_state=second;dig=8'b00000001;end
  204.                                                 second:begin next_sub_state=third;dig=8'b00000011;end
  205.                                                 third:begin next_sub_state=fourth;dig=8'b00000111;end
  206.                                                 fourth:begin next_sub_state=fifth;dig=8'b00001111;end
  207.                                                 fifth:begin next_sub_state=sixth;dig=8'b00011111;end
  208.                                                 sixth:begin next_sub_state=seventh;dig=8'b00111111;end
  209.                                                 seventh:begin next_sub_state=eighth;dig=8'b01111111;end
  210.                                                 eighth:begin next_sub_state=finish;dig=8'b11111111;end      //当输入完8位密码后状态保持不变,等待输入enter命令
  211.                                                 finish:begin next_sub_state=finish;dig=8'b11111111;end
  212.                         endcase
  213. endcase
  214. else
  215. next_sub_state=sub_state;
  216. end
  217. //记录密码
  218. always@(posedge clk or negedge resetb)
  219. begin
  220.           if(!resetb)
  221.           inputpassword<=0;
  222.           else if(cmd_t==0)
  223.                 case(sub_state)
  224.                         first:inputpassword[31:28]<=cmd[3:0];
  225.                         second:inputpassword[27:24]<=cmd[3:0];
  226.                         third:inputpassword[23:20]<=cmd[3:0];
  227.                         fourth:inputpassword[19:16]<=cmd[3:0];
  228.                         fifth:inputpassword[15:12]<=cmd[3:0];
  229.                         sixth:inputpassword[11:8]<=cmd[3:0];
  230.                         seventh:inputpassword[7:4]<=cmd[3:0];
  231.                         eighth:inputpassword[3:0]<=cmd[3:0];
  232.                         default:inputpassword<=inputpassword;
  233.                 endcase
  234.                 else
  235.                 inputpassword<=inputpassword;
  236.                 end
  237.                 //比较密码
  238.                 always@(posedge clk or negedge resetb)
  239.                 begin
  240.                 if(!resetb)//如果复位键按下则正确,错误都清零
  241.                    begin
  242.                                 correct<=0;
  243.                                 error<=0;
  244.                         end
  245.                 else if(cmd_t==0&&cmd==enter)//当按键按下,且是enter键按下时对密码进行比较
  246.                                 if(inputpassword==PASSWORD)//密码正确时correct=1
  247.                                 begin
  248.                                         correct<=1;
  249.                                         error<=0;
  250.                                 end
  251.                                 else //密码错误时,error为1
  252.                                 begin
  253.                                                 error<=1;
  254.                                                 correct<=0;
  255.                                 end
  256.                                 else
  257.                                         begin
  258.                                                 correct<=0;
  259.                                                 error<=0;
  260.                                                 end
  261. end
  262. //修改密码
  263. always@(posedge clk )
  264. begin
  265. if(cmd_t==0&&cmd==sure)
  266.     begin
  267.          PASSWORD<=inputpassword;
  268.          mimagaile<=1;
  269.          end
  270. else
  271. mimagaile<=0;
  272. end
  273. //记录错误次数
  274. always@(posedge clk or negedge resetb)
  275. begin
  276. if(!resetb)//复位时密码重试次数清零
  277.         try_count<=0;
  278.         else
  279.         if(error==1)//当输入密码错误时,重试次数加1
  280.         try_count<=try_count+2'b01;
  281.         else if(main_state==pass||main_state==alarm)//当有一次成功,重试次数超过三次后,进入报警后重试次数清零
  282.                         try_count<=0;
  283.                         end
  284.         endmodule
  285. //按键模块
  286. module scankey(clk,a,b,keyvalue);
  287. input clk;
  288. input [3:0]b;
  289. output reg[3:0]a;
  290. output reg [3:0]keyvalue;
  291. reg [1:0]q;
  292. reg [3:0] qdb;//消抖后的b
  293. reg [3:0]rxbuf;
  294. always @( posedge clk) begin //按键消抖
  295. rxbuf[0] <= b[0];
  296. qdb[0] <= ~(rxbuf[0] & (~b[0]));
  297. end
  298. always @( posedge clk) begin //按键消抖
  299. rxbuf[1] <= b[1];
  300. qdb[1] <= ~(rxbuf[1] & (~b[1]));
  301. end
  302. always @( posedge clk) begin //按键消抖
  303. rxbuf[2] <= b[2];
  304. qdb[2] <= ~(rxbuf[2] & (~b[2]));
  305. end
  306. always @( posedge clk) begin //按键消抖
  307. rxbuf[3] <= b[3];
  308. qdb[3] <= ~(rxbuf[3] & (~b[3]));
  309. end
  310. always@(posedge clk)
  311. begin q<=q+1;
  312. case(q)
  313. 0:a<=4'b1110;
  314. 1:a<=4'b1101;
  315. 2:a<=4'b1011;
  316. 3:a<=4'b0111;
  317. endcase
  318. case({a,qdb})
  319. 8'b1110_0111:keyvalue<=4'b0000;//按键0
  320. 8'b1110_1011:keyvalue<=4'b0001;//按键1
  321. 8'b1110_1101:keyvalue<=4'b0010;
  322. 8'b1110_1110:keyvalue<=4'b0011;
  323. 8'b1101_0111:keyvalue<=4'b0100;
  324. 8'b1101_1011:keyvalue<=4'b0101;
  325. 8'b1101_1101:keyvalue<=4'b0110;
  326. 8'b1101_1110:keyvalue<=4'b0111;
  327. 8'b1011_0111:keyvalue<=4'b1000;//按键8
  328. 8'b1011_1011:keyvalue<=4'b1001;//按键9
  329. 8'b1011_1101:keyvalue<=4'b1010;//确认键
  330. 8'b1011_1110:keyvalue<=4'b1011;//清除键
  331. 8'b0111_0111:keyvalue<=4'b1100;
  332. 8'b0111_1011:keyvalue<=4'b1101;//改密键
  333. 8'b0111_1101:keyvalue<=4'b1110;
  334. 8'b0111_1110:keyvalue<=4'b1111;


  335. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整论文下载(word格式 可编辑):
EDA电子密码锁课程设计报告.docx (673.02 KB, 下载次数: 188)

评分

参与人数 2黑币 +11 收起 理由
2457514212 + 5 共享资料的黑币奖励!
这货不是小武啊 + 6 赞一个!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2017-6-28 16:22 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:235109 发表于 2017-9-24 21:41 | 显示全部楼层
感谢!!十分实用~~
回复

使用道具 举报

ID:335906 发表于 2018-5-22 19:05 | 显示全部楼层
感谢楼主,我的毕设课题和这个有相似之处,很有用
回复

使用道具 举报

ID:361408 发表于 2018-6-28 22:37 来自手机 | 显示全部楼层
楼主其他的怎么看
回复

使用道具 举报

ID:538262 发表于 2019-5-14 19:57 | 显示全部楼层
感谢十分有用!
回复

使用道具 举报

ID:511206 发表于 2019-5-23 22:35 | 显示全部楼层
优秀
回复

使用道具 举报

ID:495974 发表于 2019-7-4 16:59 | 显示全部楼层
有没有实物图啊
回复

使用道具 举报

ID:514848 发表于 2019-12-17 16:48 | 显示全部楼层
优秀,我拿去借鉴了
回复

使用道具 举报

ID:790676 发表于 2020-6-27 09:25 | 显示全部楼层
很有帮助,借鉴一下
回复

使用道具 举报

ID:806589 发表于 2020-7-22 09:38 | 显示全部楼层
很有帮助,想看之后的代码
回复

使用道具 举报

ID:777603 发表于 2020-11-20 20:22 | 显示全部楼层
优秀,拿去借鉴了

回复

使用道具 举报

ID:830608 发表于 2020-12-2 10:27 | 显示全部楼层
666可以的挺有用的
回复

使用道具 举报

ID:839981 发表于 2021-1-14 15:36 | 显示全部楼层
你好,有关于引脚锁定的代码吗
回复

使用道具 举报

ID:839981 发表于 2021-1-14 15:37 | 显示全部楼层
你好,有关于引脚锁定的代码吗?
回复

使用道具 举报

ID:1054542 发表于 2022-11-29 11:34 | 显示全部楼层
楼主好了厉害,想学
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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