FPGA学习之 呼吸灯

Posted 满足没有

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA学习之 呼吸灯相关的知识,希望对你有一定的参考价值。

FPGA学习之 呼吸灯

用FPGA实现2s呼吸灯,使其达到由暗变亮再变暗的效果。

什么是呼吸灯??
呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸。

如何实现呼吸灯??
主要通过控制led灯点亮的时间来实现控制灯光的强弱,从而达到 ”呼吸“ 的效果。

设计思路:

设置一个2us和一个2ms的时钟以及一个2s的时钟计数器,其中每一级计数器都由前一个计数器的计满信号驱动,当前一个计数器计满时,后一个计数器加一。计数器计满后,归零。

2ms 时 2us的1000倍,因此可分成1000份,记作cnt1。2s也同样,记作cnt2。

当 cnt1 < cnt2 时 灯亮。
当 cnt1 > cnt2 时 灯不亮。
cnt1从0加到1000,cnt2才加1,所以灯亮的时间很短,就很暗,随着cnt2 越来越大,灯亮的时间越来越长,效果上就越来越亮。在下一个2s时进行翻转,灯就由亮逐渐变暗。

代码实现:

module led(
	input					clk,		//50MHZ
	input					rst_n,		//低电平有效
	
	output [3:0] 		led
);
	
	
	//-------------------参数定义
	

	parameter	TIME_2us = 100;			//2us		
	parameter	TIME_2ms = 100_000;		//2ms
	parameter	TIME_2s  = 100_000_000;	//2s

	reg [6:0]	cnt_base;
	reg [9:0]	cnt_1;	//2ms计数器,1000个2us
	reg [9:0]	cnt_2;	//2s计数器,1000个2ms
	reg 			valid;//标志信号
	wire	[4:0]	wave;//占空比

	//------------------2us计数器
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			cnt_base <= 7'd0;
		else
			if(cnt_base < TIME_2us - 1'b1)
				cnt_base <= cnt_base + 1'b1;
			else
				cnt_base <= 7'd0;
	end
	
	//-------------------将2ms分成1000个2us,计1000次

	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			cnt_1 <= 10'd0;
		else
			if(cnt_base == TIME_2us - 1'b1)//1us加一次
				if(cnt_1 < TIME_2ms/TIME_2us - 1'b1)
					cnt_1 <= cnt_1 + 1'b1;
				else					//记录到1000次时清零
					cnt_1 <= 10'd0;
			else
				cnt_1 <= cnt_1;
	end
	
	//------------------把2s分成1000个2ms

	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			cnt_2 <= 10'd0;
		else
			if(cnt_base == TIME_2us - 1'b1 && cnt_1 == TIME_2ms/TIME_2us - 1'b1)//计1ms加一次
				if(cnt_2 < TIME_2s/TIME_2ms - 1'b1)
					cnt_2 <= cnt_2 + 1'b1;
				else			//记录到1000次时清零
					cnt_2 <= 10'd0;
			else
				cnt_2 <= cnt_2;
	end
	
	
	assign wave = {4{(cnt_1 < cnt_2) ? 1'b1 : 1'b0}};//随着离2s越来越近,占控比增大

	//--------------------------标志信号,用于控制占空比翻转
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			valid <= 1'b0;
		else
			if(cnt_base == TIME_2us - 1'b1 && cnt_1 == TIME_2ms/TIME_2us - 1'b1 && cnt_2 == TIME_2s/TIME_2ms - 1'b1)//每两秒反转一次
				valid <= ~valid;
			else
				valid <= valid;
	end
	

	assign led = (valid == 1'b0) ? wave : ~wave;//控制led
endmodule

占空比wave 在2s内是一直增大的,效果就是LED灯逐渐变亮。
通过valid信号,来控制wave 翻转,使其在下一个2s内逐渐减小,实现灯逐渐变暗。

测试文件:

`timescale 1ns/1ns

module tb();

//激励信号定义

reg tb_clk;
reg tb_rst_n;

//输出信号参数定义
wire [3:0] tb_led;

//时钟周期
parameter CLOCK_CYCLE = 20;

led u_led(
    .clk        (tb_clk),
	.rst_n      (tb_rst_n),
    .led        (tb_led)
);


defparam    u_led.TIME_2us = 10,
            u_led.TIME_2ms = 10000,
            u_led.TIME_2s  = 10000000;


//产生时钟

initial tb_clk = 1'b0;
always #(CLOCK_CYCLE/2) tb_clk = ~tb_clk;

//产生激励

initial begin
    tb_rst_n = 1'b0;
    #(CLOCK_CYCLE *10);
    tb_rst_n = 1'b1;
end


endmodule


以上是关于FPGA学习之 呼吸灯的主要内容,如果未能解决你的问题,请参考以下文章

FPGA学习之 呼吸灯

FPGA的学习:呼吸灯

[FPGA]Verilog利用PWM调制巧妙完成RGB三色彩虹呼吸灯(给简约的题目以美妙的解答)

Simulink HDL Coder FPGA初级开发实践 LED呼吸灯

Simulink HDL Coder FPGA初级开发实践 LED呼吸灯

FPGA学习之 异步FIFO