1.要求
灯2秒内由亮变暗,两秒内由暗变亮
2.思想
先将2秒分成1000份,每份的占空比由1000/1000逐渐变为0/1000,然后下一个两秒又由0/1000变为1000/1000,循环往复
核心要点:通过比较两个计数器得到pwm波
3.程序
// FPGA : 小梅哥AC620
// EDA : Quartus II 13.0sp1 (64-bit) and ModelSim SE-64 10.5
// Author : FPGA小白758 https://blog.csdn.net/q1594?spm=1010.2135.3001.5343
// File : breath_led.v
// Create : 2022-05-04 20:16:31
// Revise : 2022-05-04 21:29:19
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module breath_led(
input wire clk ,
input wire rst_n ,
output wire led
);
parameter DIV_CNT_MAX = 99 ;
parameter TIME_CNT_MAX = 999 ;
parameter PWM_CNT_MAX = TIME_CNT_MAX ;
reg [15:0] div_cnt ; //最小分辨率计数器
reg [15:0] time_cnt ; //不同占空比的最小分辨率
reg [15:0] pwm_cnt ; //pwm计数,每个pwm_cnt值对应一个占空比
reg led_flag ; //高为有亮到暗,低为由暗到亮
//三种计数器
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
// reset
div_cnt <= 'd0;
end
else if (div_cnt == DIV_CNT_MAX - 1'b1) begin
div_cnt <= 'd0;
end
else begin
div_cnt <= div_cnt + 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
// reset
time_cnt <= 'd0;
end
else if ((div_cnt == DIV_CNT_MAX - 1'b1) & (time_cnt == TIME_CNT_MAX - 1'b1)) begin
time_cnt <= 'd0;
end
else if (div_cnt == DIV_CNT_MAX - 1'b1) begin
time_cnt <= time_cnt + 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
// reset
pwm_cnt <= 'd0;
end
else if ((div_cnt == DIV_CNT_MAX - 1'b1) & (time_cnt == TIME_CNT_MAX - 1'b1) & (pwm_cnt == PWM_CNT_MAX - 1'b1)) begin
pwm_cnt <= 'd0;
end
else if ((div_cnt == DIV_CNT_MAX - 1'b1) & (time_cnt == TIME_CNT_MAX - 1'b1))begin
pwm_cnt <= pwm_cnt + 1'b1;
end
end
//呼吸标志位
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0) begin
// reset
led_flag <= 1'b0;
end
else if ((div_cnt == DIV_CNT_MAX - 1'b1) & (time_cnt == TIME_CNT_MAX - 1'b1) & (pwm_cnt == PWM_CNT_MAX - 1'b1)) begin
led_flag <= ~led_flag;
end
end
//led控制位
assign led = led_flag ? pwm_cnt < time_cnt:pwm_cnt > time_cnt;
endmodule