新浪博客

Verilog实现pwm波控制灯的亮暗【FPGA】

2016-07-11 11:01阅读:
首先一定要明确一点!!很重要!!led灯的亮暗控制原理是什么?
led灯的亮暗是靠平均电压来控制的。
举个例子,假设把一个时钟平均分成10块,如果只有1块的时间led是导通的,剩下的9块led是截止的。假设PWM信号的幅值是5V,那么在导通的1块时间里LED电压的确是5V的,但是在剩下9块时间里,它的电压却是0V。也就是说从一个周期整体看来,LED的平均电压只有5*0.1+0*0.9=0.5V。
又由于PWM信号频率很高的,我们无法通过肉眼来观察到每一个周期LED灯亮灭的变化过程,所以人眼看到的亮暗即为通过平均电压这样一种方式显示。

大家都知道PWM波是脉冲宽度调制,用来控制一个周期中高低电平的时间(就是我们经常说的占空比),但是具体用Verilog语言来实现可能还比较陌生,下面先给一个PWM的例子。
module pwm_generate(
in_clk,

rst,
pwm_count, //控制pwm的占空比,范围0-FFFFF
out_pwm);

input in_clk;
input rst;
input [19:0] pwm_count;
output reg out_pwm;

reg [20:0] pwm_cnt;
always @ (posedge in_clk or negedge rst)
if(!rst)
pwm_cnt <= 20'b0 ;
else if(pwm_cnt == 20'hfffff) //满度,即一个周期
pwm_cnt <= 20'b0 ;
else
pwm_cnt <= pwm_cnt+1'b1 ;
//pwm生成
always @ (posedge in_clk or negedge rst)
if(!rst)
out_pwm <= 1'b0;
else if(pwm_cnt <= pwm_count)
out_pwm <= 1'b0;
else
out_pwm <= 1'b1;

endmodule

PWM程序理解:
1.可以通过改变pwm_count值来改变占空比,改变范围是根据[19:0]的大小来决定的,可以自行设置。
2.建立一个计数的变量reg [20:0] pwm_cnt,实现循环功能,一直自加1到最大值后置零,再进行自加。
3.使用并行方式,一直在检测,当pwm_cntpwm_count时,输出为高电平。

★如果你只想控制一个led的亮暗程度,用这个程序就可以了,把输出分配管脚到led就可以显示。如果想要实现呼吸灯的效果,即led自动从亮变暗再变亮的循环过程,可以看看下面的例子。
这个程序思路很好,利用了flag标志位,使用步长来控制灯亮暗的变化速度。

// Module Name: pwm_out

// Description: Led blink frequency is 50hz which can be divided from the input clk(50M)
//LED的闪烁频率是50hz,这可以从50M的晶振经过分频得到。灯每闪一次,改变一次占空比。
//LED由暗到亮,再由亮到暗,从而实现PWM控制LED灯亮度


module PWM(
clk, //50Mhz
led //output led
);

input clk;
output led;

parameter
Led_Step = 20'h00fff; //this is the data that can control the speed of the led light

reg clk_50hz;
reg[19:0] cnt;
always @(posedge clk) begin
if(cnt == (1000000-1)) begin
cnt <= 20'b0;
clk_50hz <= 1'b1;
end
else begin
cnt <= cnt + 1'b1;
clk_50hz <= 1'b0;
end
end


reg[19:0] pwm_high;
reg flag;
always @(posedge clk) begin
if(clk_50hz)
if(flag)
if(pwm_high >= (1000000-1)) begin
flag <= 1'b0; //flag0是变暗的标志
end
else
pwm_high <= pwm_high + Led_Step; //步长
else
if(pwm_high <= 20'b1) begin
flag <= 1'b1; //flag1是变亮的标志
end
else
pwm_high <= pwm_high - Led_Step;
end
assign led = (cnt < pwm_high) ? 1'b1 : 1'b0; //相当于改变占空比了

endmodule

程序下载到开发板上就能用了,可以自己根据实验现象结合程序的理解改动,主要是给新手朋友们练习使用啦~

我的更多文章

下载客户端阅读体验更佳

APP专享