本篇展示利用按键、拨码开关以及数码管实现密码锁。实验目的在原有工程上做了更改及优化,具体如下:
拨码开关SW1- SW4 设置 2 位数密码,一个拨码开关代表1bit,拨上(靠近数码管侧)为1,拨下为0.KEY1-KEY2 作为密码输入,按键按一下数字加 1,范围2bit即0--3,且KEY1,KEY2按键数值显示在数码管十位、各位(硬件上在同一侧方位)。 KEY1与bit_SW1 bit_SW2比对,KEY1与bit_SW3 bit_SW4比对,按按键KEY3进行输入与拨码比对,成功数码管显示"SUCC",失败则显示"FAIL". KEY4清0并数码管显示0000,可重设密码。数码管显示无明显频闪。
一.代码部分
1.工程配置及约束
芯片型号选择与开发板匹配PGC1KG-6LPG100,参照硬件原理,工程约束如下:
图1:工程约束
2.代码结构梳理
上层模块lock_top.v 上层模块功能定义了按键计数,拨码开关设值,按键确认与清零及数码管显示功能定义
子模块部分
(1)btn_deb.v实现按键计数,key_ctl.v按键消抖及控制设置密码及数码管显示
(2)compare.v实现按键值与拨码开关值比较,并返回真假结果
(3)seq_display.v数码管显示,seq_control.v根据键值设置数码管参数,div_clk.v数码管刷新时钟配置
3.代码准备
这里做一定修改,及按键侧与数码管显示侧在一边不镜像,便于操作理解方便更好体验。另外原工程数码管显示频闪严重,这里一并优化。
3.1配置更改
(1)为按键与拨码开关及数码管左右对应上,修改lock_top.v及compare.v,里sw。
module lock_top(
input clk,
input [1:0] key,
input enter,
input init,
input [0:3] sw,
output [7:0] smg,
output [3:0] dig
);
(2)key_ctl.v 改assign ctrl = {key1_push_cnt,key2_push_cnt}; //KEY1显示在数码管十位,KEY2显示在数码管各位。
(3)seq_display.v将比较结果显示更改为成功SUCC,失败FAIL.
注意这里在0-9基础上增加了6个,所以要用5bit位宽
图2:数码管显示增加代码
(4)数码管段位显示“S”,"U","C","F","A","I","L"
key定义为5bit位,代码修改如下
图3:数码管段位显示增加case(key)键值
3.2代码优化
原工程数码管显示频闪严重,这里我修改了div_clk.v,将频率由1KHz改到10KHz, 数码管显示消抖 ,代码修改如下,消除闪烁,效果见文末尾视频
图4:数码管消抖代码修改
至此,代码部分修改及优化完毕
二.调试测验
1.编译烧录
2.设置密码,且正确,如下图
图5:密码正确解锁成功
密码错误解锁失败如下
图6:密码错误解锁失败
在调试过程中,有遇到"FAIL"最后一个"L"显示成0,后检查发现是seq_control.v里key位宽不够溢出导致,相关部分改为5bit解决了。异常显示如下图
图7:数码管显示异常
三.小结
本次学习,更进一步掌握代码结构,Verlog语法的使用,在数码管显示异常、抖动方面,通过发现问题解决问题锻炼了能力,增添了学习FPGA兴趣,收获满满。
文末附上源代码和视频,以供分享学习
更多回帖