0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于FPGA的呼吸灯设计(附源工程)

FPGA技术江湖 来源:FPGA技术江湖 2025-01-16 10:09 次阅读

设计背景

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

设计原理

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

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

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

e46d969a-d2db-11ef-9310-92fbcf53809c.png

使用一系列等幅不等宽的脉冲来代替一个正弦波,脉冲的宽度根据正弦波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时钟

e48b8a6a-d2db-11ef-9310-92fbcf53809c.png

设计代码

设计模块huxi_led_state代码:

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 
仿真测试

测试模块代码:

`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 
仿真图:

e4ce0f02-d2db-11ef-9310-92fbcf53809c.png

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

END

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1638

    文章

    21856

    浏览量

    609431
  • 脉冲
    +关注

    关注

    20

    文章

    899

    浏览量

    96196
  • 呼吸灯
    +关注

    关注

    10

    文章

    111

    浏览量

    42913

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

文章出处:【微信号:HXSLH1010101010,微信公众号:FPGA技术江湖】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    相关推荐

    【瑞萨RA2L1入门学习】01. PWM 呼吸

    占空比的调节就是实现呼吸效果的关键。通过控制PWM信号的占空比,可以实现对LED亮度的连续调节。在递增占空比阶段,LED亮度逐渐增加;在递减占空比阶段,LED亮度逐渐降低。使用循环来控制的方式来实现
    发表于 03-07 11:43

    ADS1298R外部呼吸模式和内部呼吸模式的区别?

    请问下大家ADS1298R中关于呼吸的模式,是怎么选择,表示没有看懂DATASHEET上写的,弄不清楚外部呼吸模式和内部呼吸模式的区别?
    发表于 01-22 06:16

    基于FPGA的VGA驱动设计(工程)

      设计背景 VGA (Video Graphics Array) 即视频图形阵列,是IBM于1987年随PS/2机(PersonalSystem 2)一起推出的使用模拟信号的一种视频传输标准。这个标准对于现今的个人电脑市场已经十分过时。但在当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域取得了广泛的应用,是众多制造商所共同支持的一个低标准。   设计原理 VGA的实体图与接口示意图,如下图所示,它有15个针孔: 在本次设计使用的开发板中,VGA的电路原理图如下图所示: 通过原理
    的头像 发表于 01-14 11:31 379次阅读
    基于<b class='flag-5'>FPGA</b>的VGA驱动设计(<b class='flag-5'>附</b><b class='flag-5'>源</b><b class='flag-5'>工程</b>)

    ADS1292R的呼吸阻抗检测功能在运动模式下是否有办法能提取出准确的呼吸信号?

    最近在用ADS1292R做心电及呼吸检测,目前情况是采用演示板的心电及呼吸采集电路。静止状态下呼吸检测波形较好,对呼吸的识别相对比较容易,但是运动模式下(测量时憋气,反复抬手臂的状态
    发表于 12-30 06:18

    ADS1191如何测呼吸

    看手册说可以应用体育和建身(心率,呼吸和ECG),我想问一下这款芯片如何测呼吸
    发表于 12-24 07:08

    ADS1292R采集呼吸波采样率越高,采样得到的呼吸波幅度越低,为什么?

    ADS1292R采样呼吸波,使用250HZ采样频率得到的呼吸波幅度比使用1KHZ采样频率得到的呼吸波幅度大2-3倍左右。正常来说不是采用频率越高,采样的波形更准确吗?有人知道是什么原因吗?求解,我
    发表于 12-06 07:32

    AMC1303E输出接的Altera FPGA,通过FPGA解码后输出总是突然来个变异的大数据,为什么?

    AMC1303E输出接的Altera FPGA,解码输出后数据流总是有问题: 正常数据下,通过FPGA解码后输出总是突然来个变异的大数据,无规律,间隔几秒钟。单独给AMC1303原边和边提供
    发表于 12-03 07:08

    多平台FPGA工程快速移植与构建

    作为一名FPGA工程师,经常需要在多个FPGA设备之间移植项目,核心的问题是IP的管理和移植,今天通过安装和使用 FuseSoC 在多个 AMD FPGA 之间移植一个简单的项目。从
    的头像 发表于 11-20 16:12 1476次阅读
    多平台<b class='flag-5'>FPGA</b><b class='flag-5'>工程</b>快速移植与构建

    4G模组PWM调光入门:打造个性化呼吸

    一直有朋友问我怎么打造个性化呼吸,本文我将以合宙低功耗4G模组经典型号——Air780E为例,展示PWM输出呼吸的实现方法,帮助大家深入理解如何在项目中应用PWM技术。
    的头像 发表于 11-17 09:56 421次阅读
    4G模组PWM调光入门:打造个性化<b class='flag-5'>呼吸</b><b class='flag-5'>灯</b>

    呼吸的概念和实现原理

    呼吸在日常生活中经常见到,如电子时钟,小夜灯等等,本文我们介绍下通过PWM波来控制LED,实现呼吸功能。
    的头像 发表于 10-24 14:50 2945次阅读
    <b class='flag-5'>呼吸</b><b class='flag-5'>灯</b>的概念和实现原理

    使用STM32CubeMX输出PWM,并制作呼吸效果

    概述 本篇文章主要介绍如何使用STM32CubeMX输出PWM,并制作呼吸效果。 硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板: 选择芯片型号 配置时钟
    发表于 09-04 10:38

    艾为灯语呼吸系列产品的应用领域

    多色绚烂的光源交相辉映,构成了一幅流动着光影之美的画卷,极富视觉冲击力。艾为灯语呼吸系列产品,历经发展,现已广泛渗透至智能手机、物联网(IoT)、智能家居以及汽车行业等诸多前沿领域,展现了其在多元化应用场景中的创新与适应能力。
    的头像 发表于 08-27 14:12 1321次阅读

    在stm8-discovery板上 如何实现呼吸的效果?

    在stm8-discovery板上如何实现呼吸的效果,pwm程序如下,请指教,谢谢! #include\"iostm8l152c6.h\" #include\"
    发表于 05-07 06:31

    源码系列:基于FPGA的红外线遥控系统设计(工程

    今天给大侠带来基于FPGA的红外线遥控系统设计,源码,获取源码,请在“FPGA技术江湖”公众号内回复“红外线遥控系统设计源码”,可获取源码文件。话不多说,上货。 前言 红外线
    发表于 05-01 19:59

    如何用pwm编程实现呼吸效果?

    我用的是stm8l152c6 下面是我的pwm 信号 求解答 如何实现呼吸 #include\"iostm8l152c6.h\" #include\"
    发表于 04-16 06:52