您现在的位置是:首页 > 编程 > 

源码系列:基于FPGA的呼吸灯设计(附源工程)

2025-07-27 06:44:27
源码系列:基于FPGA的呼吸灯设计(附源工程) 大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。 今天给大侠带来基于FPGA的呼吸灯设计,附源码,获取源码,请在“FPGA技术江湖”内回复“呼吸灯设计源码”,可获取源码文件。话不多说,上货。设计背景呼吸灯广泛应用于

源码系列:基于FPGA的呼吸灯设计(附源工程)

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

今天给大侠带来基于FPGA的呼吸灯设计,附源码,获取源码,请在“FPGA技术江湖”内回复“呼吸灯设计源码”,可获取源码文件。话不多说,上货。

设计背景

呼吸灯广泛应用于手机之上,并成为各大品牌新款手机的卖点之一。如果手机里面有未处理的通知,比如说未接来电,未查收的等等,呼吸灯就会在控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸,起到一个通知提醒的作用。

设计原理

关于呼吸灯设计实现的理论主要是PWM有关知识。PWM(Pluse Width Modulation)脉冲宽度调制,是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。并广泛应用在从测量、通信、功率控制与变换及LED照明等许多领域中。顾名思义,就是占空比可调的信号,那么什么是占空比呢?

占空比(Duty Cycle or Duty Ratio),可以解释为,在一脉冲序列中(方波),正脉冲序列的持续时间与脉冲总周期的比值。也可理解为,电路释放能量的有效时间与总释放时间的比值。

PWM是怎样实现调光呢?想要调节LED的亮度变化,实则是调节控制流经LED的电流。电流增大则LED亮度增强,反之减弱。但由于电流为模拟信号,所以这时就用到了PWM。正如下图所示:

使用一系列等幅不等宽的脉冲来代替一个正弦波,脉冲的宽度根据正弦波a的幅度变化,幅度高,则脉冲宽,反之。

多数负载需要的PWM调制频率都高于10Hz,要想实现呼吸灯的效果,必须提高调制频率,通常调制频率为1Khz~200Khz之间。在LED控制中PWM作用于电源部分,脉宽调制的脉冲频率通常大于100Hz,人眼就不会感到闪烁。这里我们取PWM调制频率为1KHz,PWM周期为1ms。

脉冲频率一定时,输出脉冲的占空比越大,相当于输出的有效电平越大,随着占空比的不同,LED的亮度也将不同。如占空比为0时,则LED不亮,为100%时,则LED最亮,我们让占空比从0~100%变化,再从100%~0不断变化,则就可实现呼吸灯效果。

本设计呼吸灯的一个周期为2s,分为占空比增“吸”和占空比减“呼”两种模式,每个为1s,一个PWM周期为2ms,所以每个模式包含1000个PWM周期,将每个PWM周期分为1000份,即每个时间段2us。

设计框架

设计框架图:

50M时钟

设计代码

设计模块huxi_led_state代码:

代码语言:javascript代码运行次数:0运行复制
module huxi_led_state(clk,led,rst_n);
  input clk;
  input rst_n;
  
  output reg led;
  
  parameter T = 100_000;
  
  localparam s0 = 1'b0;
  localparam s1 = 1'b1;
  
  reg [25:0] lw;
  reg [25:0] hw;
  
  reg [16:0] count;
  
  // 产生2MS的脉冲
  always @(posedge clk or negedge rst_n)
    if(!rst_n)
      begin
        count <= 1'b0;
      end
    else
      begin
        if(count == T - 1)
          begin
            count <= 1'b0;
          end
        else
          begin
            count <= count + 1'b1;
          end
      end
      
  wire flag;
  assign flag =(count == T - 1) ? 1'b1:1'b0;
  
  reg state;
  
  // 通过在一个周期中加减高低电平的时间来产生PWM波
  always @(posedge clk or negedge rst_n)
    if(!rst_n)
      begin
        lw <= T - 100;
        hw <= 100;
        state <= 1'b0;
      end
    else
      begin
        case (state)
          s0:begin
              if(flag && (lw > 100))   //判断低电平的时间
                begin
                  lw <= lw - 100;
                  hw <= hw + 100;
                  state <= s0;
                end
              else if(flag && (lw == 100))
                begin
                  hw <= hw - 100;
                  lw <= lw + 100;
                  state <= s1;
                end
              else
                begin
                  hw <= hw;
                  lw <= lw;
                  state <= s0;
                end
            end
          s1:begin
              if(flag && (hw > 100))   //判断高电平的时间
                begin
                  hw <= hw - 100;
                  lw <= lw + 100;
                  state <= s1;
                end
              else if(flag && (hw ==100))
                begin
                  hw <= hw + 100;
                  lw <= lw - 100;
                  state <= s0;
                end
              else
                begin
                  hw <= hw;
                  lw <= lw;
                  state <= s1;
                end
            end
        default : state <= s0;
        endcase
      end
      
  reg [25:0] cnt;
  reg sum;  
  always @(posedge clk or negedge rst_n)
    if(!rst_n)
      begin
        sum <= 1'b0;
        led <= 1'b1;
        cnt <= 1'b0; 
      end
    else
        case (sum)
          s0:begin
              if(cnt < hw -1 )
                begin
                  led <= 1'b0;
                  cnt <= cnt + 1'b1;
                end
              else
                begin
                  cnt <= 1'b0;
                  sum <= s1;
                end
            end
          s1:begin
              if(cnt < lw -1)
                begin
                  led <= 1'b1;
                  cnt <= cnt + 1'b1;
                end
              else
                begin
                  cnt <= 1'b0;
                  sum <= s0;
                end
            end
          default:sum <= s0;
        endcase
  
endmodule 

仿真测试

测试模块代码:

代码语言:javascript代码运行次数:0运行复制
`timescale 1ns/1ps 
  module huxi_led_state_tb();
  reg clk;
  reg rst_n;
  
  wire led;
  
  parameter T = 100_000;
  
  initial begin
      clk = 1'b1;
      rst_n = 1'b0;
      
      #200.1 rst_n = 1'b1;
      
      
    end
    
    always #10 clk = ~ clk; 
  
  
  
  huxi_led_state  huxi_led_state_date(
          .clk(clk),
          .led(led),
          .rst_n(rst_n)
          );
  endmodule 

仿真图:

仿真中可以看到点亮led等高电平在不停的增高,然后会降低,通过验证我们的设计是正确的。

本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2025-01-14,如有侵权请联系 cloudcommunity@tencent 删除设计手机源码fpga测试

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1176249.html

相关标签:无
上传时间: 2025-07-21 17:39:11
留言与评论(共有 10 条评论)
本站网友 跨境贸易人民币结算
11分钟前 发表
输出脉冲的占空比越大
本站网友 丹参片的作用
21分钟前 发表
反之减弱
本站网友 岂言不贪欢
17分钟前 发表
脉宽调制的脉冲频率通常大于100Hz
本站网友 金钟民
24分钟前 发表
欢迎来到FPGA技术江湖
本站网友 上城二手房
29分钟前 发表
起到一个通知提醒的作用
本站网友 viewer
21分钟前 发表
通信
本站网友 石家庄洗浴
5分钟前 发表
如果手机里面有未处理的通知
本站网友 学士服
24分钟前 发表
通过高分辨率计数器的使用
本站网友 怀男孩和女孩的区别
7分钟前 发表
为100%时