FPGA之呼吸灯

基础知识      

        呼吸灯的效果是灯逐渐由暗变亮再逐渐由亮变暗,FPGA的引脚电压只有“0”和“1”两个等级。因此通过改变引脚单位时间内高电平的输出时间来实现呼吸灯,也就是让FPGA引脚输出一系列PWM波信号并不断改变PWM波的占空比。

        PWM(Pluse Width Modulation)脉冲宽度调制,是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。占空比(Duty Cycle or Duty Ratio),可以解释为,在一脉冲序列中(方波),正脉冲序列的持续时间与脉冲总周期的比值。也可理解为,电路释放能量的有效时间与总释放时间的比值。

FPGA之呼吸灯_第1张图片

FPGA之呼吸灯_第2张图片

波形图

FPGA之呼吸灯_第3张图片

 代码

module breach_led
#(
	parameter CNT_1US_MAX = 6'd49,
	parameter CNT_1MS_MAX = 10'd999,
	parameter CNT_1S_MAX  = 10'd999
)
(
	input	wire	sys_clk,
	input	wire	sys_rst_n,
	
	output	reg 	led_out
);
reg	[9:0]cnt_1s;
reg	[9:0]cnt_1ms;
reg	[5:0]cnt_1us;
reg cnt_en;

always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
		cnt_1us <= 6'd0;
	else if (cnt_1us == CNT_1US_MAX)
		cnt_1us <= 6'd0;
	else
		cnt_1us <= cnt_1us + 6'd1;
end
	
always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
		cnt_1ms <= 10'd0;
	else if ((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
		cnt_1ms <= 10'd0;
	else if(cnt_1us == CNT_1US_MAX)
		cnt_1ms <= cnt_1ms + 10'd1;
	else
		cnt_1ms <= cnt_1ms;
end

always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
		cnt_1s <= 10'd0;
	else if ((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
		cnt_1s <= 10'd0;
	else if ((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
		cnt_1s <= cnt_1s + 10'd1;
	else
		cnt_1s <= cnt_1s;
end

always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
		cnt_en <= 1'b0;
	else if((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
		cnt_en <= ~cnt_en;
	else
		cnt_en <= cnt_en;
end
	
always @(posedge sys_clk or negedge sys_rst_n)
begin
	if(!sys_rst_n)
		led_out <= 1'b1;
	else if(((cnt_en == 1'b0)&&(cnt_1ms <= cnt_1s))||((cnt_en == 1'b1)&&(cnt_1ms > cnt_1s)))
		led_out <= 1'b0;
	else
		led_out <= 1'b1;
end

endmodule
`timescale 1ns/1ns
module tb_breach_led();

	reg sys_clk;
	reg sys_rst_n;
	wire led_out;
	
initial
	begin	
		sys_clk = 1'b1;
		sys_rst_n <= 1'b0;
		#20
		sys_rst_n <= 1'b1;
	end
always #10 sys_clk <= ~sys_clk;

breach_led 
#(
	.CNT_1US_MAX (6'd4),
	.CNT_1MS_MAX (10'd9),
	.CNT_1S_MAX  (10'd9)
)
breach_led_inst
(
	.sys_clk	(sys_clk),
	.sys_rst_n	(sys_rst_n),
			
	.led_out    (led_out)
);

endmodule

 仿真

FPGA之呼吸灯_第4张图片

FPGA之呼吸灯_第5张图片

你可能感兴趣的:(野火学习笔记,fpga开发)