最简洁的呼吸灯实验(verilog)
前言
网上PWM呼吸灯的案例很多,但有些案例代码太复杂,这里展示一下我写的,目前最简洁的
一、PWM呼吸等的原理
产生一个三角波,累加或递减一个计数器,然后在N个三角波周期内用一个累加和递减的计数器和这些三角比较,产生PWM波形
二、示例
module pwm_led(
input clk_25MHz,
input state_pb,//复位信号
output PWM_out_LED
);
wire clk_pwm;
reg [4:0] clk_cnt=5'd0; //降低计数器时钟频率
reg [9:0] pwm_tri_cnt1=10'd0; //三角波计数
reg [9:0] pwm_mode_cnt2=10'd0; //载波计数
reg flag=1'b0; //递增和递减标志
parameter up=10'd1000;
parameter down=10'd1;
always@(posedge clk_25MHz)begin
clk_cnt<=clk_cnt+1'b1;
end
assign clk_pwm=&clk_cnt;//产生一个低频计数时钟信号
always@(posedge clk_25MHz)
if (clk_pwm) begin
pwm_tri_cnt1<=(state_pb||pwm_tri_cnt1==up)?10'd0:pwm_tri_cnt1+1'b1;//生成三角波
if (pwm_tri_cnt1==up) begin
pwm_mode_cnt2 <= flag? pwm_mode_cnt2-1'b1:pwm_mode_cnt2+1'b1;//生成调制波
end
flag <= pwm_mode_cnt2==up?1'b1:(pwm_mode_cnt2==down?1'b0:flag);
end
assign PWM_out_LED=(pwm_mode_cnt2>pwm_tri_cnt1)?1'b1:1'b0;//载波和调制波比较,产生PWM波
endmodule
这个过程中只需要依据时钟修改clk_cnt,因为一般输入时钟太高。N选择1000就可以了,100左右能看到led有点闪烁,1000左右亮度稳定,太大的话呼吸效果不明显。
三、总结
这样的PWM呼吸灯的效果不是很好,因为占空比是线性递增和递减的,而实际上LED等的亮度和PWM波的占空比不成正比,所以感觉亮的时间长,暗的时间短,LED灯的亮度和电流有关,要想精确控制LED灯的闪烁效果(苹果电脑上的呼吸灯那样),还需要做很多非线性调制设计,欢迎讨论。