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分为两组,每组以不同的频率呼吸。

相关推荐

  1. 05. 基于Verilog呼吸程序设计

    2024-05-09 17:56:03       40 阅读
  2. 02.0 基于Verilog控制LED每秒钟闪烁一次

    2024-05-09 17:56:03       30 阅读
  3. 02.3 基于Verilog控制多个LED以不同频率闪烁

    2024-05-09 17:56:03       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 17:56:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 17:56:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 17:56:03       82 阅读
  4. Python语言-面向对象

    2024-05-09 17:56:03       91 阅读

热门阅读

  1. numpy常用方法

    2024-05-09 17:56:03       32 阅读
  2. filebeat处理k8s docker模式下部署导致deviceid改变

    2024-05-09 17:56:03       31 阅读
  3. Python基础之流程控制语句

    2024-05-09 17:56:03       35 阅读
  4. css实现元素内容过高时自动出现展开收起按钮

    2024-05-09 17:56:03       33 阅读
  5. 25 | MySQL是怎么保证高可用的?

    2024-05-09 17:56:03       35 阅读