【连载】【FPGA黑金开发板】Verilog HDL那些事儿数码管电路驱动(八)

声明:本文为原创作品,版权归akuei2及黑金动力社区(http://www.heijin.org)共同所有,如需转载,请注明出处http://www.cnblogs.com/kingst/

P7302375_thumb

3.1 实验七:数码管电路驱动

学习过单片机的朋友,多多少少都对数码管有些认识吧?关于这些基础知识,我就不再重复了,因为网上已经有一大堆这样的资料。我曾经学过不同驱动方法,但是从黑金开发板的电路来看,我觉得设计者真的很GOOD JOB。因为黑金开发板所承载的电路很基础,所以它才有学习的价值。

clip_image002

clip_image004

数码管是共阳,而是用PNP管来反响驱动并且控制列扫描(SEL0_T和SEL1_T)。而且所有的数码管的“段选信号”(LEDA .. LEDH)都共用同样的引脚。结论来说,数码管都信号都是“低电平有效”。

实验七的实验目的,是设计现实最大为99数字在2个数码管资源上。采取的现实方法是同步动态扫描。估计“动态扫描”应该学习过吧, “同步动态扫描”是指“行信号”和“列信号”同步扫描。换句话说,是真正意义上的并行操作。

我们先看看实验七要建立的模块:

clip_image006

实验七的组合模块 exp07_top.v 是又四个功能模块组成。每一个功能模块都如本身的命名一样。程序的设计思路如下:

“十位取位模块”接收最大为99的数目。然后由该模块进行取位的操作,将十位和各位划分,然后输出独自的信号线 Ten_Data 和 One_Data。中间是“SMG加码模块”,将由二进制组成的数目“转换”成SMG码。Ten_Data 和 One_Data 被转换后,再经Ten_SMG_Data 和 One_SMG_Data 输出。最后由“扫描模块”smg_can_module.v ,执行“同步动态扫描”点亮数码管。

3.1.1 number_mod_module.v

clip_image008

“number_mod_module.v”的设计很简单,就是利用数学运算符“%”和“/”分别取得十位和各位。因为是十位取位的关系,所以最大的输入数是00~99而已。

clip_image010

上面的源码比较简单。但是有几点可能会造成读者的困惑。在第16~17行声明了32位的寄存器,寄存器的目的是在第27~28行,用来保存取位结果的十位和个位。但是为什么是32位呢?

我记得在quartus II 9.0 版本中 ,“除法器”可以自己定义。但是在 10.0 版本,这些选项就消失了。尤其是说消失,还不如说更“默认化”了。默认下“除法器”和“求余器”是32位输出。但是经过“编译”过后,编译器会“自动优化”最适合的位宽。所以这也是为什么,在16~17行的声明是32位呢!除此之外,“除法器”和“求余器”.v 文件会“自动添加”在原本 .v 文件的层次之下。

clip_image012

编译后的“除法器”和“求余器”

clip_image014

编译过后的.v 文件

3.1.2 smg_encoder_module.v

clip_image016

clip_image018

clip_image019

设计依然也是很简单,第17~20行声明了SMG码的常量。第24~45行是针对“十位数”的加码操作(32行)。第50~71行也是同样的操作,但是是针对“个位数”(58行)。第75~76行是输出。

3.1.3 smg_scan_module.v

clip_image021

smg_scan_module.v 无疑是 row_scan_module.v 和 column_scan_module.v 的组合模块。无论是“行扫描模块”还是“列扫描模块”,扫描频率都制定位 50hz。

column_scan_module.v

clip_image023

因为实验七的要求是两个数码管资源,假设各个数码管使能的时间是10ms,两个数码管所占用的时间自然是20ms。换句话说,就是完成一次扫描占用20ms的周期时间。

然而 column_scan_module.v 是执行“列扫描”。说得简单点,就是每隔10ms就使能不同的数码管。

clip_image025

clip_image026

第12行声明了10ms的常量。第16~24行是10ms的定时器,而28~36行是用来控制扫描的次序。寄存器 t 表示了当前的扫描,是0还是1(是第0个数码管或者第1个数码管)。第40~61行是 column_scan_module.v 的具体操作。当t等于0是将第0个数码管使能(拉低),当t等于1是将第1个数码管使能(拉低)。

row_scan_module.v

理解 column_scan_module.v 过后,我们来理解 row_scan_module.v 从字面是“行扫描”的意思。基于 column_scan_module.v 我们知道该模块每隔10ms使能不同的数码管资源,而 row_scan_module.v 的功能也非常相似。Row_scan_module.v 主要是每隔10ms,输出不同的SMG码。具体的操作还是看代码:

clip_image028

clip_image029

第16~40行,完全是和 column_scan_module.v 一样。在44~55行 row_scan_module.v 每隔10ms的时间输出不同的SMG码。在t等于0的时候输出“Ten_SMG_Data”(第52行),当t等于1的时候输出 “One_SMG_Data”(第53行)。

smg_scan_module.v

smg_scan_module.v 的组合模块。代码比较简单,直接看代码吧。

clip_image031

总体来说 smg_scan_module.v 的功能可以用以下图表来表示:

时间

列扫描

行扫描

初始化

T0

使能第0个数码管资源

十位的SMG码

T1

使能第1个数码管资源

个位的SMG码

完成扩展图:

clip_image033

3.1.4 exp07_top.v

clip_image035

实验七说明:

在总体的理解,我们之所以很自然的自右向左去理解,具体的原因是发生“图形”的效果上。因为“图形”将实验七描述,既是“从左输入,向右输出”。在我们明白每一个模块的功能之后,再经由“连线关系”,自然而然很容易明白完整模块的操作。

完成扩展图:

clip_image037

实验七结论:

实验七是一个完整且初级的“低级建模”,而且建模条件完全按照“低级建模”的准则。

虽然“低级建模”的建模量是而外的多,但是对此,却使得设计更灵活。除此之外“一个模块一个功能”与“连线关系”使整体的解读性大大提升。

实验七的设计单单是针对“2个数码管资源”,当然你也可以自行修改前它扩展到支持“六个数码管资源”与“0~999999”,又或者修改其他的。

实验七演示:

实验七的演示,是建立一个0~15的计数器。然后这个计数器会直接驱动 exp07_top.v 的 Number_Data 输入信号。

clip_image039

clip_image041

clip_image042

实验七演示说明:

第14行定义了1s的常量,而第18~41是15s的计数器。第43~54行实例化exp07_top 为U1。在第49行,利用Counter_Sec,直接驱动exp07_01 的输入口。

完成扩展图:

clip_image044

实验七演示结论:

这只是简单的演示,演示主要是指南 exp07_top 的调用。

原文地址:https://www.cnblogs.com/kingst/p/1832180.html