1 呼吸灯简介
呼吸灯采用 PWM 的方式,在固定的频率下,通过调整占空比的方式来控制 LED
灯亮度的变化。
PWM (Pulse Width Modulation
),即脉冲宽度调制,它利用微处理器输出的
PWM
信号,实现对模拟电路控制的一种非常有效的技术,广泛应用于测量、通信、功率控制等领域。
在由计数器产生的固定周期的 PWM
信号下,如果其占空比为
0
,则
LED
灯不亮;如果其占空比为 100%,则
LED
灯最亮。所以将占空比从
0
到
100%
,再从
100%
到
0
不断变化,就可以实现
LED
灯的“呼吸”效果。
2 实验任务
实现呼吸灯的效果。
3 硬件设计
#IO 管脚约束set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports led]
4 程序设计
周期信号计数器用于产生驱动 LED
的脉冲信号,本次实验的周期信号频率为
1Khz
,其占空比由后级逻辑在每个周期之后进行递增或递减,最后再对当前计数值和占空比计数值进行比较,以输出占空比可调的脉冲信号。
呼吸灯代码如下:
module breath_led(
input sys_clk , //时钟信号 50Mhz
input sys_rst_n , //复位信号
output led //LED
);
//reg define
reg [15:0] period_cnt ; //周期计数器频率:1khz 周期:1ms 计数值:1ms/20ns=50000
reg [15:0] duty_cycle ; //占空比数值
reg inc_dec_flag ; //0 递增 1 递减
//*****************************************************
//** main code
//*****************************************************
//根据占空比和计数值之间的大小关系来输出 LED
assign led = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
//周期计数器
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
period_cnt <= 16'd0;
else if(period_cnt == 16'd50000)
period_cnt <= 16'd0;
else
period_cnt <= period_cnt + 1'b1;
end
//在周期计数器的节拍下递增或递减占空比
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
duty_cycle <= 16'd0;
inc_dec_flag <= 1'b0;
end
else begin
if(period_cnt == 16'd50000) begin //计满 1ms
if(inc_dec_flag == 1'b0) begin //占空比递增状态
if(duty_cycle == 16'd50000) //如果占空比已递增至最大
inc_dec_flag <= 1'b1; //则占空比开始递减
else //否则占空比以 25 为单位递增
duty_cycle <= duty_cycle + 16'd25;
end
else begin //占空比递减状态
if(duty_cycle == 16'd0) //如果占空比已递减至 0
inc_dec_flag <= 1'b0; //则占空比开始递增
else //否则占空比以 25 为单位递减
duty_cycle <= duty_cycle - 16'd25;
end
end
end
end
endmodule