一、呼吸灯简介
呼吸灯:由灭渐亮,然后再由亮渐灭,模仿人呼吸方式的LED灯,
二、呼吸灯原理
PWM(Pulse Width Modulation),脉冲宽度调制,

三、代码
四个呼吸灯代码
//首先module开始模块
module breath_led(
input sys_clk,
input sys_rst_n,
output [3:0] led
);
//然后开始生成一个pwm波,在一段时间内,我们的占空比由小变大,再由大变小这样子一个脉冲调制,它就是一个pwm波。
//定义一个计数器,时间周期做多长,呼吸灯效果最好,可以做一个尝试,确定之后要把位宽给定下来,电脑调出计算器,win+r,输入calc
//1毫秒除以20纳秒=50000,50000换成2进制是16位,所以需要16位位宽,要给它定义成[0-15],20纳秒是晶振,
reg [15:0] period_cnt;
//第一个空占25,第二个空占50,第三个空占75,不断累加,占空比越占越宽,当占到50000之后占满了,再开始减小,再25、25的减再减到0,这样就实现了一个pwm波的产生。
reg [15:0] duty_cycle;
//定义一个寄存器,用来控制我们这个占空比是往上加还是往上减,增加减少标志位
reg inc_dec_flag;
assign led[0] = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
assign led[1] = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
assign led[2] = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
assign led[3] = (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
//定义一个时间段,做周期计数器
always @(posedge sys_clk or negedge sys_rst_n)begin//定义一个时间段,做周期计数器
if(!sys_rst_n)//if 复位,计数器清零
period_cnt<=0;
else if(period_cnt==16'd50000)//没有复位的时候,它要数五万次,没到五万次让它加一,到了五万次让它清0。
period_cnt<=0;
else //没到五万次让它加一,到了五万次让它清0。
period_cnt<=period_cnt+1'b1;
end
//要做一个占空
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin//if 复位,计数器清零,标志位清零
duty_cycle<=0;
inc_dec_flag<=0;
end
else begin
if(period_cnt==16'd50000)begin //先判定他有没有执行完一个完整的周期
if (inc_dec_flag<=0)begin //再判定inc_dec_flag标志位状态是否为0
if(duty_cycle==16'd50000) //再判定duty_cycle有没有增到50000
inc_dec_flag<=1; //增加到50000,标志位反转
else //没增加到50000,duty_cycle增加25
duty_cycle<=duty_cycle+25;
end
else begin //如果inc_dec_flag标志位状态为1,则执行
if(duty_cycle==16'd0) //如果duty_cycle为0
inc_dec_flag<=0; //则标志位为0
else //如果duty_cycle不为0
duty_cycle<=duty_cycle-25; //duty_cycle减少25
end
end
end
end
endmodule