一、PWM简介
PWM(Pulse Width Modulation,脉冲宽度调制)是一种用于控制模拟信号的数字技术。它通过改变脉冲信号的宽度来表示模拟信号的幅度。PWM常用于电子设备中,如电机驱动、LED调光、音频放大器等应用。
他的基本原理是产生一系列脉冲信号,其宽度(脉冲持续时间)可以调整。通常,PWM信号是由一个固定频率的周期性脉冲和一个可变的占空比组成。
频率:在1秒钟内,信号从高电平到低电平再回到高电平的次数。
占空比:指在一个脉冲周期内,高电平的时间占整个周期时间的比例。
脉冲宽度:在一个脉冲周期内,信号高电平所占的时间。
二、呼吸灯项目
呼吸灯是一种特殊的 LED 灯效果,模拟人类呼吸的渐变效果。这种效果通常通过改变 LED 的亮度来实现,使得灯光在周期性的增强和减弱之间变化,就像人类呼吸时胸腔的起伏一样。本文使用PWM方法,编写适当的算法来调整 PWM 信号的占空比,从而实现呼吸灯效果的时间变化。当占空比越高时,LED灯越亮。实现原理框图如下所示。
主要包括计数器和占空比调节部分。设一个完整的呼吸周期为100ms,设置两个计数器cnt和duty_cycle(占空比),当cnt计数到5_000_000时(也就是100ms),占空比变化一次。duty_cycle=duty_cycle+25(duty_cycle的自增可以根据需要调整)。当duty_cycle增加到5_000_000时,将其重新置零。于是当cnt>duty_cycle时,我们让LED灯亮,这样随着duty_cycle的增加LED的亮度就会逐渐减弱。assign led = (cnt > duty_cycle) ? 1'b1 : 1'b0;
同时还需要考虑到呼吸灯变亮的情况,因此引入inc_dec,当inc_dec为1时,占空比增加,呼吸灯逐渐变亮,为0时,占空比减少,呼吸灯逐渐变暗。在每一个呼吸周期结束后,也即cnt增加到5_000_000时,inc_dec翻转。
实现代码如下:
module breath_led(
input sys_clk ,
input sys_rst_n,
output wire led
);
reg [19:0] cnt ;
reg [19:0] duty_cycle;
reg inc_dec ;//inc_dec为1时,占空比增加,为0时,占空比减少
wire add_cnt ;
wire end_cnt ;
//计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 20'd0;
else if(add_cnt)
if(end_cnt)
cnt <= 20'd0;
else
cnt <= cnt+1'b1;
end
assign add_cnt = (cnt != 20'd5_000_000) ? 1'b1 : 1'b0;
assign end_cnt = (cnt == 20'd5_000_000) ? 1'b1 : 1'b0;
//PWM实现
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
duty_cycle <= 20'd0;
inc_dec <= 1'b0 ;
end
else begin
if(cnt == 20'd5_000_000)
begin
if(inc_dec == 1'b1)begin
if (duty_cycle == 20'd5_000_000)
inc_dec <= 1'b0;
else
inc_dec <= inc_dec;
duty_cycle <= duty_cycle + 16'd50;
end
else begin
if(duty_cycle == 20'd0)
inc_dec <= 1'b1;
else
inc_dec <= inc_dec;
duty_cycle <= duty_cycle - 16'd50;
end
end
end
end
//对LED灯赋值
assign led = (cnt > duty_cycle) ? 1'b1 : 1'b0;
endmodule
当cnt计到5_000_000(100ms)时,inc_dec=1占空比呈递增状态,如果占空比已经增加到最大值(5_000_000),则inc_dec=0,让其变为递减状态,否则占空比以50为单位递增;inc_dec=0时,占空比呈递减状态,如果占空比已递减到0,则inc_dec=1,让其变为递增状态,否则以50为单位递减。
测试代码如下:
`timescale 1 ns/ 1 ps
module breath_led_vlg_tst();
reg sys_clk;
reg sys_rst_n;
wire led;
breath_led i1 (
.led(led),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n)
);
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#80 sys_rst_n = 1'b1;
end
always #10 sys_clk = ~sys_clk;
endmodule
为了方便看仿真波形,cnt最大值设为50,duty_cycle每次自增5,波形图如下:
三、QuartusII与ModelSim联合仿真
在联合仿真之前需要将仿真工具设置为ModelSim。
assignment——settings——Simulations,将Tool name设为ModelSim,地址指向ModelSim下载地址中的win64,Complie中找到test bench文件,然后点击Apply,OK。
点击Tools——options——EDA Tool Options,同样将地址指向ModelSim下载地址中的win64。
然后点击Tools——Run Simulation Tool——RTL Simulation,就可以调出ModelSim直接看到波形图了。
##本文参考正点原子视频,如有侵权,请联系删除。