模块接口说明
信号 | 方向 | 描述 |
---|
clk | 输入 | 系统时钟(100MHz,周期10ns) |
rst_n | 输入 | 低电平有效的异步复位信号 |
led_en | 输入 | 总使能信号(1=开启呼吸灯,0=关闭) |
speed_en | 输入 | 呼吸速度调节使能信号 |
speed[2:0] | 输入 | 呼吸速度分级(0-7对应8级速度,0最慢,7最快) |
led | 输出 | 即PWM输出(受led_en 控制) |
模块代码:
/* 呼吸灯模块例化
led_breath #(.STEP (1)
) led_breath(.clk (clk ), .rst_n (rst_n ),.led_en (led_en ),.speed_en (speed_en), .speed (speed ),.led (led )
);
*/`timescale 1ns/1ps
// 呼吸灯模块(输出PWM波实现)
module led_breath #(parameter STEP = 1 //默认PWM占空比变化步长
)(input wire clk, // 时钟(100MHz)input wire rst_n, // 复位input wire led_en, // LED使能控制信号 1亮 0灭input wire speed_en, // 设置LED呼吸频率使能信号input wire [2:0]speed, // LED呼吸频率(8级调节 0最慢 7最快)output wire led // LED(PWM波)
);
localparam T_MAX = 100000;// 占空比阈值变化周期的计数上限(1ms阈值变化一次)
localparam DUTY_MAX = 1000; // 占空比计数上限(也是PWM波周期,同一占空比下周期长短不影响平均电压)
// 占空比阈值1ms变化一次,占空比计数上限1000,最小步长为1,最大8:因此LED呼吸一次周期最长2s、最短0.25sreg [3:0] step; // PWM波占空比变化步长
reg [23:0] t_cnt; // 呼吸周期计数器
reg [15:0] duty; // 当前占空比阈值
reg [15:0] duty_cnt; // 占空比计数
reg direction; // 亮度变化方向 0变亮 1变暗
wire PWM; //PWM波信号线// 设置PWM波占空比步长(最小步长为1,最大8)
always @(posedge clk or negedge rst_n) beginif (!rst_n) step <= STEP;else if (speed_en)step <= (speed==7) ? 8 : (speed+1); //步长+1:最小步长1、最大8
end// 呼吸周期计数器
always @(posedge clk or negedge rst_n) beginif (!rst_n) t_cnt <= 0;else if (t_cnt == T_MAX-1)t_cnt <= 0;elset_cnt <= t_cnt + 1;
end// PWM占空比阈值变化
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginduty <= 0;direction <= 0;endelse if (t_cnt == T_MAX-1) begin if (direction == 0) begin //变亮if (duty +step < DUTY_MAX) //防止占空比阈值不超过最大duty <= duty + step;elsedirection <= 1;endelse begin //变暗if (duty -step > 0 && duty -step < DUTY_MAX) //防止减法溢出的情况duty <= duty - step;elsedirection <= 0;endend
end// 占空比计数器
always @(posedge clk or negedge rst_n) beginif (!rst_n)duty_cnt <= 0;else if (duty_cnt == DUTY_MAX-1)duty_cnt <= 0;elseduty_cnt <= duty_cnt + 1;
end
// PWM波输出
assign PWM = (duty_cnt <= duty);// LED使能输出
assign led = led_en && PWM;endmodule