【FPGA】三、LED流水灯控制

文章目录

前言

一、LED流水灯实验

1.实验目的

2.程序设计

3.仿真验证:

总结


前言

        通过前面一章LED呼吸灯的实验,我们已经基本上了解了LED灯的物理特性,也对利用FPGA控制LED灯有了初步的了解,那么这一篇文章就是在上一篇的基础上增加了一些小的功能,不仅需要实现LED灯的亮灭,还要有规律的亮灭,实现多个LED灯的流水灯效果。


一、LED流水灯实验

1.实验目的

        实现开发板上4个LED灯顺序点亮并熄灭,循环往复产生流水的现象。

2.程序设计

        由于二极管的阳级分别与FPGA相应的管脚相连,只需要改变与LED灯相连的FPGA管脚的电平,LED灯的亮灭状态就会发生改变。当FPGA管脚为高电平时,LED灯点亮;为低电平时,LED灯熄灭。

        根据人的视觉暂留效应,这里我们让流水灯每隔0.2s变化一次,如果变化时间太快,人眼就不能捕捉到流水灯的视觉效果了。

流水灯模块代码如下:

/*========================================*
    filename    : flow_led.v
    description : led流水灯实验
    time        : 2022-11-08 
    author      : 卡夫卡与海
*========================================*/

module flow_led(
    input                clk     ,//系统时钟 50MHZ
    input                rst_n   ,//系统复位

    output  reg  [3:0]   led      //4个LED灯
);
//参数定义
parameter   TIME_200ms = 24'd10_000_000;//计数0.2s

//信号定义
reg    [23:0]     cnt_200ms   ;//计数器,计数200ms

//cnt 计算器对系统时钟计数,计数200ms
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_200ms <= 24'd0;
    end
    else if(cnt_200ms == (TIME_200ms - 1))begin
        cnt_200ms <= 24'd0;
    end
    else begin
        cnt_200ms <= cnt_200ms + 1'b1;
    end
end

//通过移位寄存器控制IO口的高低电平,改变LED的显示状态
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        led <= 4'b0001;
    end
    else if(cnt_200ms == (TIME_200ms - 1))begin
        led[3:0] <= {led[2:0],led[3]};
    end
    else begin
        led <= led;
    end
end

endmodule

测试模块代码如下:

`timescale 1ns/1ns   //定义仿真时间单位1ns和仿真时间精度1ns

module flow_led_tb(); //测试模块
    reg           clk   ;//时钟信号
    reg           rst_n ;//复位信号

    wire  [3:0]   led   ;

//参数定义
parameter   CYCLE_CLOCK = 20;//时钟周期为20ns
parameter   RST_TIME = 40 ;//复位时间定义

//产生时钟
initial begin
    clk = 1'b0;
    forever 
    #(CYCLE_CLOCK/2)
    clk = ~clk;
end

//产生复位
initial begin
    rst_n = 1'b0;
    #(RST_TIME);
    rst_n = 1'b1;
    #10000;
    $stop;
end

//模块例化
flow_led u_flow_led(
    /*input                */.clk     (clk  ),//系统时钟 50MHZ
    /*input                */.rst_n   (rst_n),//系统复位

    /*output  reg  [3:0]   */.led     (led  ) //4个LED灯
);

endmodule

说明:

        本程序的系统时钟为50MHZ,一个周期为20ns。

        每当计数器计数到10-000-000时,将各个LED灯状态左移一位,并将最高位的值移到最低位,循环往复,在其他时间段内,LED灯的状态保持不变。且LED灯的初始值必须有一位为1,其他为是0,这样在循环左移的过程中才能呈现出流水灯的效果。

3.仿真验证:

仿真波形如下:

         这里为了减少仿真过程中所需要的时间,我把流水灯变化的时间改为了100ns变化一次。从Modelsim的仿真波形来看,LED灯的变化顺序为0001→0010→0100→1000,符合我们预想的效果。


总结

        到此为止,LED灯的基本实验及内容就是这些了,感兴趣的小伙伴还可以利用LED灯去做更加复杂的逻辑控制,但是需要一个清晰的思路,那样会事半功倍,在有必要的时候还可以画一画时序图,最后看看仿真出来的时序图是否与你所画的时序图匹配。

猜你喜欢

转载自blog.csdn.net/weixin_62912626/article/details/127748455