基础 -1- 流水灯
约 1149 个字 59 行代码 4 张图片 预计阅读时间 5 分钟
章节导读 ¶
流水灯实验作为基础实验的第一个实验是非常合适的,本章我们利用试验箱中的 LED 进行点亮 LED,并实现流水灯的功能。
理论学习 ¶
相信大家之前肯定接触过单片机等设备,而学习这些设备的第一个实验例程往往都是点亮一个 LED。本次实验在点亮 LED 的基础上另 LED 灯依次闪亮,循环不止,实现“流水”的功能。其原理是依次控制连接到 LED 的 IO 口的电平高低,让 LED 的闪亮间隔为 0.5s,以实现流水灯的效果。
实战演练 ¶
实验目标 ¶
依次点亮实验板中的 8 个 LED 灯,两灯点亮间隔为 0.5s,每次点亮持续 0.5s,实现流水灯效果。
硬件资源 ¶
实验板上有 0~31 共 32 个 LED 灯的资源,每 4 个 LED 灯为一组,分别是绿,红,蓝,黄四种颜色,本次实验使用 8 个 LED 进行验证。
Figure 1. LED 扩展板
通过原理图可以得知,本试验箱的 LED 灯为高电平时点亮。
Figure 2. LED 扩展板原理图
程序设计 ¶
流水灯的设计与分频器,计数器的逻辑相似,只是多了 LED 灯的点亮部分。为了实现计数器肯定需要时钟信号 sysclk,也需要一个复位信号 rstn,同时为了驱动 LED,需要 8 个 IO 口。所以模块的端口如下表所示:
| 端口名称 | 端口位宽 | 端口类型 | 功能描述 |
|---|---|---|---|
| sysclk | 1Bit | Input | 输入时钟,频率 27M |
| rstn | 1Bit | Input | 复位信号,低电平有效 |
| led | 8Bit | Output | LED 控制信号 |
Table 1. 模块端口列表
为了使灯点亮 0.5s,我们应该设计一个计数器或者是分频器,先将板载 27M 高频时钟降速。在 27M 时钟下计数 0.5s,需要计数器计数 13_500_000 个数,也就是计数器从 0 开始计数到 13_499_999。所以我们定义一个寄存器 cnt,每一次时钟上升沿 cnt 就加 1,当计数到 13_499_999 时,led 的状态改变,同时 cnt 归零重新开始计数。
为了实现 8 个 led 流水的效果,我们将 0 定义为 led 灭,1 表示亮,初始状态 led = 8’b0000_0001,当经过 0.5s 后,也就是 cnt 等于 13_499_999 的时候,第一个 led 灭,第二个 led 亮起,也就是 led = 8‘b0000_0010。同理,再过 0.5s,led = 8’b0000_0100,再过 0.5s,led = 8‘b0000_1000 以此类推。
根据上面的规律我们很容易发现,led 的流水是靠 1 的移位来实现的,也就是最基本的左移 (<<) 和右移 (>>) 运算符去实现。在这里我们需要向左移位,并且每次只需要移动 1 位。模块的参考代码(waterled_top.v)如下所示:
仿真验证 ¶
为上述模块编写仿真模块,参考代码(waterled_top_tb.v)如下:
为了加速仿真,我们在仿真文件中另 CNT_MAX 的值为 100。同时为了便于仿真,可以直接点击 sim 文件夹下 hebav 文件夹中的 do.bat 文件即可利用 ModuleSim 对模块进行仿真,仿真波形如下:
Figure 3. 流水灯仿真波形(一)
Figure 4. 流水灯仿真波形(二)
从图 3 我们可以看到,端口信号 led 的值经过一定时间之后就进行了左移,并且在图 4 中我们也可以发现,当 cnt 的值等于 CNT_MAX 的时候 led 进行左移,与我们设计的目标相符合,可以进行下一步上板验证了。
上板验证 ¶
仿真已经通过,可以进行上板验证,上板前要先进行管脚约束。端口与对应管脚如下表所示:
| 端口名称 | 信号类型 | 对应管脚 | 功能 |
|---|---|---|---|
| sysclk | Input | 时钟 | |
| rstn | Input | 复位 | |
| led[0] | Output | LED | |
| led[1] | Output | LED | |
| led[2] | Output | LED | |
| led[3] | Output | LED | |
| led[4] | Output | LED | |
| led[5] | Output | LED | |
| led[6] | Output | LED | |
| led[7] | Output | LED |
Table 2. 端口与管脚对应列表
管脚分配可以直接编写 .fdc 文件,也可以使用 PDS 内置的工具进行分配。
完成管脚分配之后就可以生成 sbit 文件,将文件提交到网站后点击烧录,即可将 sbit 下载到实验板中,在摄像头页面即可观察到流水灯的现象。
章末总结 ¶
本次实验主要学习使用左移<<和右移>>运算符实现移位,但实际应用中也可以使用位拼接{}进行更加复杂的移位操作,各位同学可以尝试学习。



