一、呼吸灯
能够产生呼吸灯有两种方式,第一种是通过调节电压的改变从而达到改变led灯的亮度,使其产生呼吸灯的效果,第二种是采取pwm波的形式,通过改变亮灭的占空比从而产生呼吸灯的效果。在fpga中改变电压控制led不太现实,所以就目前的学习程度来说还是采用pwm的形式。
二、实现
1.波形
(1)从亮到灭
由于板子上面的led是低电平点亮,所以此波形图主要是从亮慢慢变灭。但是另外一种情况由灭到亮也是通过led_out来输出,因此需要一个标志位cnt_led_en的低电平表示从亮到灭的过程,这个过程持续一秒钟,根据根据三个计数器的值计算可得。cnt_1us计满49向进1,而 cnt_1ms计满999向cnt_1s进1,直到cnt_1s计到999时,此时正好计数49999999共1s,对标志位取反进入由灭到亮的过程,从而循环往复。
(2)从灭到亮
(3)仿真波形
(4)输出条件
led_out的值时根据标志位以及cnt_1ms 和cnt_1s的大小共同确定输出时高电平还是低电平。其判断条件如下
2、程序
module breath_led
#(
parameter CNT_MAX_1US = 6’d49,
parameter CNT_MAX_1MS = 10’d999,
parameter CNT_MAX_1S = 10’d999
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out
);
reg [5:0] cnt_1us;
reg [9:0] cnt_1ms;
reg [9:0] cnt_1s;
reg cnt_1s_en;
always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1us <= 6’d0;
else if (cnt_1us == CNT_MAX_1US)
cnt_1us <= 6’d0;
else
cnt_1us <= cnt_1us + 6’d1;
always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1ms <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS))
cnt_1ms <= 10’d0;
else if (cnt_1us == CNT_MAX_1US)
cnt_1ms <= cnt_1ms + 10’d1;
else
cnt_1ms <= cnt_1ms;
always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1s <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS)&&(cnt_1s == CNT_MAX_1S))
cnt_1s <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS))
cnt_1s <= cnt_1s + 10’d1;
else
cnt_1s <= cnt_1s;
always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1s_en <= 1’b0;
else if ((cnt_1s == CNT_MAX_1S)&&(cnt_1ms == CNT_MAX_1MS)&&(cnt_1us == CNT_MAX_1US))
cnt_1s_en <= ~cnt_1s_en;
else
cnt_1s_en <= cnt_1s_en;
always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
led_out <= 1’b0;
else if (((cnt_1ms <= cnt_1s)&&(cnt_1s_en == 1’b1))
||((cnt_1ms >= cnt_1s)&&(cnt_1s_en == 1’b0)))
led_out <= 1’b0;
else if (((cnt_1ms > cnt_1s)&&(cnt_1s_en == 1’b1))
||((cnt_1ms < cnt_1s)&&(cnt_1s_en == 1’b0)))
led_out <= 1’b1;
else
led_out <= led_out;
endmodule
仿真程序
`timescale 1ns/1ns
module tb_breath_led ();
reg sys_clk;
reg sys_rst_n;
wire led_out;
initial
begin
sys_clk = 1’b0;
sys_rst_n <= 1’b0;
#20
sys_rst_n <= 1’b1;
end
always #10 sys_clk = ~sys_clk;
breath_led
#(
.CNT_MAX_1US(6’d20) ,
.CNT_MAX_1MS(10’d24) ,
.CNT_MAX_1S (10’d24)
)
breath_led_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n) ,
.led_out (led_out)
);
endmodule