05. 基于Verilog的呼吸灯程序设计

05_led_breath_v0

一个基于Verilog的呼吸灯程序示例,该程序通过PWM(脉冲宽度调制)技术来模拟呼吸灯的效果,逐渐变亮再逐渐变暗的LED灯,给人一种灯光在“呼吸”的感觉。

原理解释:

  1. PWM(脉冲宽度调制):通过改变输出信号的占空比来模拟不同亮度的LED灯。

  2. 呼吸灯周期:呼吸灯的周期由breathing_cnt控制,这里假设周期为1/4秒钟。

  3. 呼吸灯亮度变化:呼吸灯的亮度变化通过改变占空比的值来模拟。

  • 当pwm_cnt小于当前pwm_duty时,LED亮;
  • 当pwm_cnt大于pwm_duty时,LED不亮。

知识点:

  • PWM(脉冲宽度调制)
  • Duty(占空比)
  • 位宽确定可表达的最大整数值
  • 位拼接语法 assign led = {6{led_breathing}};
module led_breath #(
    parameter CLK_FREQ = 50000000,
    parameter LED_ON = 1'b0
)(
    input wire clk,       
    input wire rst_n,     
    output wire [5:0] led      
);

// 定义一个计数器用于产生PWM波形
reg [11:0] pwm_cnt;
reg [11:0] pwm_duty;

reg [31:0] breath_cnt;

// 呼吸灯周期,假设为1秒钟4个周期
localparam CYCLE = CLK_FREQ/4;

always @(posedge clk) begin
    if (!rst_n) breath_cnt <= 0;
    else begin
        breath_cnt <= breath_cnt + 1'b1;
        if (breath_cnt == CYCLE-1) breath_cnt <= 0;
    end
end

wire breath_done = (breath_cnt == CYCLE-1);

//PWM CNT
always @(posedge clk) begin
    if (!rst_n) pwm_cnt <= 0;
    else pwm_cnt <= pwm_cnt + 1'b1;
end

//PWM Duty
//light to off
always @(posedge clk) begin
    if (!rst_n) pwm_duty <= 12'hFFF;
    else if(breath_done) begin
        if(pwm_duty == 0) pwm_duty <= 12'hFFF;
        else pwm_duty <= {1'b0,pwm_duty[11:1]};
    end
    //else pwm_duty <= pwm_duty;
end

/*
//off to light on
always @(posedge clk) begin
    if (!rst_n) pwm_duty <= 12'b0;
    else if(breath_done) begin
        if(pwm_duty == 12'hFFF) pwm_duty <= 12'b0;
        else pwm_duty <= {pwm_duty[10:0],1'b1};
    end
    //else pwm_duty <= pwm_duty;
end
*/

// 根据PWM计数器的值和呼吸灯的亮度变化来控制LED的亮度
reg led_breathing;
//parameter LED_ON = 1'b0; //led active low on our board
localparam LED_OFF = ~LED_ON;

always @(posedge clk) begin
    if (!rst_n) led_breathing <= LED_OFF;
    else if (pwm_cnt < pwm_duty) begin
        led_breathing <= LED_ON;
    end else led_breathing <= LED_OFF;
end

assign led = {6{led_breathing}};

endmodule

扩展思维

  1. 学习了点亮LED、LED闪烁、LED跑马灯和LED呼吸灯这样多种模式LED效果,思考如何将这些不同的效果在一个工程里全部实现,并利用DIP开关选择不同的运行模式,呈现不同的效果。

  2. 尝试修改代码实现6个LED分为两组,每组以不同的频率呼吸。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值