流水灯实验作为一个经典的入门实验,其地位堪比编程界的 “ Hello World ” 。对于许多同学来说,流水灯都是他们在硬件上观察到的第一个实验现象。流水灯是指多个LED灯按照一定的时间间隔,顺序点亮并熄灭,周而复始形成流水效果。本文我将记录我学习使用FPGA做流水灯实验的过程。

1 实验内容

        本次实验的内容就是使开发板上的四个LED灯以0.5秒的间隔按顺序亮灭,循环往复从而产生流水的效果。

2 硬件电路设计

                                                                         图2.1  LED指示灯电路

         由图2.1可知,LED的阳极与3.3V电源相连,阴极通过一个1K的限流电阻与相应的FPGA的管脚相连,当FPGA管脚为低电平时,LED灯点亮,反之,则熄灭。

端口名称   I/0 功能描述 对应管脚
Clk50M input 模块的工作时钟,频率为50M

PIN_E1

Rst_n input 模块复位,低电平复位 PIN_E16
led[0] output 低电平时LED亮 PIN_A2
led[1] output 低电平时LED亮 PIN_B3
led[2] output 低电平时LED亮 PIN_A4
led[3] output 低电平时LED亮

PIN_A3

                                                                            图2.2 流水灯实验管脚分配

3 程序设计

          程序原理图如图3.1所示

                                                                               图3.1 程序原理图

       在上一次实验中我已成功实现了计数器计数,因此在本次实验中采用计数器累加计数来计时的方法来达到计时0.5秒的目的。 计时 达0.5s 后计数器清零并重新开始计数,这样就得到了固定的时间间隔,从而使LED灯以0.5s的间隔亮灭。

       流水灯模块部分的代码如下:

module counter(Clk50M,Rst_n,led);
	input Clk50M; //系统时钟
	input Rst_n;  //全局复位 低电平复位
	
	output reg [3:0] led;//led 输出
	
	reg [24:0]cnt;//定义25位寄存器
	//计数器计数进程
	always@(posedge Clk50M or negedge Rst_n)//最后一条执行完成后,再开始执行其中的第一条语句,如此往复循环,直到整个仿真结束,对一组反复执行的活动进行建模
		if(Rst_n == 1'b0)
			cnt <= 25'b0;
		else if(cnt == 25'd24_999_999)
			cnt <= 25'b0;
		else 
			cnt <= cnt + 1'b1;
	//LED输出控制进程		0.5s 翻转一次
	always@(posedge Clk50M or negedge Rst_n) begin
		if(Rst_n == 1'b0)
			led <= 4'b0001;
		else if(cnt == 25'd24_999_999)
			led[3:0] <= {led[2:0] , led[3]} ;
		else 
			led <= led;
		end
endmodule 

       学习板上晶振为50MHz,也就是说时钟周期为 20ns,这样可以计算得出 500ms = 500_000_000ns/20,即需要计数器 计数 25_000_000 次,也就是需要一个至少 25 位的计数器( 位的计数器( 225>25_000_000>224 )。且每当计数次达到需要清零并重新计数。当计数器计满25_000_000 次时,将各个LED灯的状态右移一位,并将最高位移至最低位,循环往复。好了,至此一个流水灯程序已经编写完毕,接下来就是下载验证啦。

 

本文地址:https://blog.csdn.net/Prague123zw/article/details/85939659