呼吸灯的实现原理过去在初学电子技术的我的脑中一直是一个迷,后来知道了有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)beginif(!res_n)period_cnt<=16'd0;else if(period_cnt==16'd50000)period_cnt<=16'd0;elseperiod_cnt<=period_cnt+1'd1;
endalways@(posedge clk or negedge res_n)beginif(!res_n)beginduty_cycle<=1'd0;inc_dec_flag<=1'b0;endelse beginif(period_cnt==16'd50000)beginif(inc_dec_flag==1'b0)beginif(duty_cycle==16'd50000)inc_dec_flag=1'b1;elseduty_cycle<=duty_cycle+16'd25;endelse beginif(duty_cycle==16'd0)inc_dec_flag=1'b0;elseduty_cycle<=duty_cycle-16'd25;end endend
end
endmodule
//testbench文件
`timescale 1ns / 1nsmodule 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;
endendmodule
4.代码讲解
assign led=(period_cnt>=duty_cycle)?1’b1:1’b0;
Verilog语言是并行执行,所以通过改变duty_cycle的值,再与period_cnt进行比较,即可改变输入LED灯的PWM方波占空比,实现呼吸灯效果。
5.仿真结果
可以看到led信号的占空比随着时间的推移而改变