呼吸灯的实现原理过去在初学电子技术的我的脑中一直是一个迷,后来知道了有PWM脉冲宽度调制这么一个方法可以实现呼吸灯,无奈因为本人过懒,没有在开发板上敲过呼吸灯的代码。恰巧本人最近在学FPGA,里面有一课专门讲呼吸灯,看来这次势必要敲一个呼吸灯的代码出来了。
1.设计思路
给LED灯输入PWM波,期间改变占空比即可实现呼吸灯的效果
假设
输入占空比为0%的PWM波 对应亮度为0%
输入占空比为33%的PWM波 对应亮度为33%
输入占空比为66%的PWM波 对应亮度为66%
PWM波占空比改变越细腻 呼吸灯的效果就越好
2.系统框图
3.代码
文章编辑器竟然没法添加Verilog代码 关键字高亮无法显示 晕
//设计文件
module breath_led(
input clk,
input res_n,
output led
);
reg [15:0] period_cnt;//1KHz
reg [15:0] duty_cycle;
reg inc_dec_flag;//0为上升,1为下降
assign led=(period_cnt>=duty_cycle)?1'b1:1'b0;
always@(posedge clk or negedge res_n)begin
if(!res_n)
period_cnt<=16'd0;
else if(period_cnt==16'd50000)
period_cnt<=16'd0;
else
period_cnt<=period_cnt+1'd1;
end
always@(posedge clk or negedge res_n)begin
if(!res_n)begin
duty_cycle<=1'd0;
inc_dec_flag<=1'b0;
end
else begin
if(period_cnt==16'd50000)begin
if(inc_dec_flag==1'b0)begin
if(duty_cycle==16'd50000)
inc_dec_flag=1'b1;
else
duty_cycle<=duty_cycle+16'd25;
end
else begin
if(duty_cycle==16'd0)
inc_dec_flag=1'b0;
else
duty_cycle<=duty_cycle-16'd25;
end
end
end
end
endmodule
//testbench文件
`timescale 1ns / 1ns
module breath_led_tb();
reg clk;
reg res_n;
wire led;
breath_led breath_led(
.clk(clk),
.res_n(res_n),
.led(led)
);
always #20 clk=~clk;
initial begin
clk=1'b1;
res_n=1'b0;
#200
res_n=1'b1;
end
endmodule
4.代码讲解
assign led=(period_cnt>=duty_cycle)?1’b1:1’b0;
Verilog语言是并行执行,所以通过改变duty_cycle的值,再与period_cnt进行比较,即可改变输入LED灯的PWM方波占空比,实现呼吸灯效果。
5.仿真结果
可以看到led信号的占空比随着时间的推移而改变