FPGA学习篇之呼吸灯

FPGA学习篇之呼吸灯

文章目录

  • FPGA学习篇之呼吸灯
  • 前言
  • 一、参数指定
  • 二、代码编写
  • 三、总结


前言

  用单片机产生占空比渐变的PWM波控制LED可以产生呼吸灯的效果,单片机能做到,FPGA同样能做到。

一、参数指定

  在编写代码之前,首先要明确以下几个概念:

  1. 呼吸周期:也就是LED灯完成一次呼吸循环的时间,期间LED灯从灭到亮再到灭,代码中定义呼吸周期为2S,从灭到亮1S,从亮到灭1S。
  2. PWM周期:调整一次LED亮灭的时间。本代码中PWM周期为1MS,PWM周期越小,每个呼吸周期内调整的次数就越多,LED呼吸效果就越丝滑。
  3. PWM精度:一个PWM周期内PWM占空比能改变的最小值,同样的PWM精度越小,LED呼吸效果也越丝滑,本代码中PWM精度为1US。

二、代码编写

  本代码时钟频率为50MHz,呼吸周期为2S。如果要修改呼吸周期和PWM周期,可以修改参数。

module breath_led #(
	parameter CNT_1S_MAX   = 999 ,  // 
	parameter CNT_1MS_MAX  = 999 ,  // 
	parameter CNT_1US_MAX  = 49     // 
)(
	input clk_in,
	input rst_n,
	output reg led
);
reg [9:0] cnt_1s;  
reg [9:0] cnt_1ms;  
reg [5:0] cnt_1us;  
reg [0:0] led_dir;  

always@(posedge clk_in or negedge rst_n)
	if(!rst_n)
		cnt_1us <= 'h0;
	else if(cnt_1us == CNT_1US_MAX)
		cnt_1us <= 'h0;
	else
		cnt_1us <= cnt_1us + 1'b1;
	
always@(posedge clk_in or negedge rst_n)
	if(!rst_n)
		cnt_1ms <= 'h0;
	else if((cnt_1us == CNT_1US_MAX) && (cnt_1ms == CNT_1MS_MAX))
		cnt_1ms <= 'h0;
	else if(cnt_1us == CNT_1US_MAX)	
		cnt_1ms <= cnt_1ms + 1'b1;
		
always@(posedge clk_in or negedge rst_n)
	if(!rst_n)
		cnt_1s <= 'h0;
	else if((cnt_1us == CNT_1US_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1s == CNT_1S_MAX))
		cnt_1s <= 'h0;
	else  if((cnt_1us == CNT_1US_MAX) && (cnt_1ms == CNT_1MS_MAX))	
		cnt_1s <= cnt_1s + 1'b1;	
		
always@(posedge clk_in or negedge rst_n)
	if(!rst_n)
		led_dir <= 1'b0;
	else if((cnt_1us == CNT_1US_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1s == CNT_1S_MAX))
		led_dir <= ~led_dir;

always@(posedge clk_in or negedge rst_n)
	if(!rst_n)
		led <= 1'b0;
	else if(((led_dir == 1'b0) && (cnt_1ms < cnt_1s)) || ((led_dir == 1'b1) && (cnt_1ms > cnt_1s)))
		led <= 1'b1;
	else
		led <= 1'b0;
endmodule

FPGA学习篇之呼吸灯_第1张图片

三、总结

  呼吸灯是计数器的简单应用,通过呼吸灯我们可以理解PWM的控制原理与思想。

你可能感兴趣的:(fpga开发)