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

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

3天内不再提示

基于FPGA的呼吸灯设计

CHANBAEK 来源:小小研究生 作者: xxyjs2020 2023-06-27 17:39 次阅读

设计规划

呼吸灯的效果是LED灯在一段时间内从完全熄灭的状态逐渐变到最亮,再在同样的时间段内逐渐达到完全熄灭的状态。这里我们需要实现1s内实现从灭到亮,1s内从亮到灭。

LED的明亮有两种方式,第一种是在安全范围内给LED灯不同的供电电压可以控制明灭;第二种是通过控制PWM的 占空比 ,同一时间段内供给LED灯一个脉冲信号的低电平持续时间越长,LED灯越亮。我们取n个相同的时间段,让低电平的持续时间按照相等的时间间隔逐渐增多,led灯就会越来越亮了。

首先我们将1s分为1000个时间段,每段1ms。再将1ms分为1000个时间小段,每段1us。第一个1ms内亮0us(灭),并在第二个1ms内亮1us,...,在第1000个1ms内亮999us。划分的等级越多,看上去效果越好,但是人眼分辨率有限,大于这个分辨率就看起来几乎没有差异。

我们至少需要三个计数器,用来计时1s,1ms,1us。cnt_1us需要从0计数到49,不复位就计数,计满就清零。cnt_1ms完全没必要重新产生,每当cnt_1ms计数到999且cnt_1us计数到49,cnt_1ms就清零。cnt_1s同理在cnt_1ms计数到999且cnt_1us计数到49时就清零。

图片

led_out要在不同时间段低电平持续时长慢慢增加,需要一个小技巧。观察上图,LED为低电平时,cnt_1s是0时,cnt_1ms是1-999;cnt_1s是1时,cnt_1ms是2-999...

图片

LED灯从亮到灭是相反的过程,LED灯为高电平时,cnt_1s>cnt_1ms。

区分从灭到亮和从亮到灭,可以使用一个电平标志信号(使能)cnt_1s_en。cnt_1s_en为低电平时实现呼吸灯从灭到亮的过程,cnt_1s_en为高的时候实现呼吸灯从亮到灭的过程,cnt_1s清零时cnt_1s_en取反。

图片

图片

编写代码

module breath_led
#(
parameter CNT_1US_MAX = 6'd49 ,
parameter CNT_1MS_MAX = 10'd999 ,
parameter CNT_1S_MAX = 10'd999
)
(
input wire sys_clk , 
input wire sys_rst_n , 
output reg led_out 
 );


 //reg define
 reg [5:0] cnt_1us ;
 reg [9:0] cnt_1ms ;
 reg [9:0] cnt_1s ;
 reg cnt_1s_en ;


 //cnt_1us:1us计数器
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 cnt_1us <= 6'b0;
 else if(cnt_1us == CNT_1US_MAX)
 cnt_1us <= 6'b0;
 else
 cnt_1us <= cnt_1us + 1'b1;


 //cnt_1ms:1ms计数器
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 cnt_1ms <= 10'b0;
 else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
 cnt_1ms <= 10'b0;
 else if(cnt_1us == CNT_1US_MAX)
 cnt_1ms <= cnt_1ms + 1'b1;


 //cnt_1s:1s计数器
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 cnt_1s <= 10'b0;
 else if(cnt_1s == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX
 && cnt_1us == CNT_1US_MAX)
 cnt_1s <= 10'b0;
 else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
 cnt_1s <= cnt_1s + 1'b1;


 //cnt_1s_en:1s计数器标志信号
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 cnt_1s_en <= 1'b0;
 else if(cnt_1s == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX
 && cnt_1us == CNT_1US_MAX)
 cnt_1s_en <= ~cnt_1s_en;


 //led_out:输出信号连接到外部的led灯
 always@(posedge sys_clk or negedge sys_rst_n)
 if(sys_rst_n == 1'b0)
 led_out <= 1'b0;
 else if((cnt_1s_en == 1'b1 && cnt_1ms < cnt_1s)||
 (cnt_1s_en == 1'b0 && cnt_1ms > cnt_1s))
 led_out <= 1'b0;
 else
 led_out <= 1'b1;
 endmodule

参数定义,输入输出定义,中间信号(计数器和使能信号)定义都是很熟悉的。

1us计数器 :复位有效时拉低电平;计满时清零;其他情况+1。

1ms计数器 :复位有效时拉低电平;计满时清零(计满条件是达到CNT_1MS_MAX和CNT_1US_MAX);达到CNT_1US_MAX时+1。

1s计数器 :复位有效时拉低电平;计满时清零(计满条件是达到CNT_1S_MAX,CNT_1MS_MAX和CNT_1US_MAX);达到CNT_1MS_MAX且CNT_1US_MAX时+1。

1s使能 :复位有效时拉低电平,计满1s时取反(达到CNT_1S_MAX,CNT_1MS_MAX和CNT_1US_MAX,和1s计数器的清零条件一样)。

led_out :复位有效时拉低电平,使能为高电平且cnt_1mscnt_1s时led_out拉低,反之拉高。

图片

编写testbench

`timescale 1ns/1ns
module tb_breath_led();
//wire define
wire led_out ;
//reg define
reg sys_clk ;
reg sys_rst_n ;


 //初始化系统时钟、全局复位
 initial begin
 sys_clk = 1'b1;
 sys_rst_n <= 1'b0;
 #20
 sys_rst_n <= 1'b1;
 end


//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50MHz
 always #10 sys_clk = ~sys_clk;


//-------------------- breath_led_inst --------------------
 breath_led
 #(
 .CNT_1US_MAX(6'd4 ),
 .CNT_1MS_MAX(10'd9 ),
 .CNT_1S_MAX (10'd9 )
 )
 breath_led_inst
 (
 .sys_clk (sys_clk ), 
 .sys_rst_n (sys_rst_n ), 
 .led_out (led_out ) 
 );


 endmodule

信号定义,初始化,规定时钟频率,参数设置(参数设置得小一点节省时间),实例化

对比波形

cnt_1ns,cnt_1ms,cnt_1s,cnt_1s_en是中间信号,查看波形需要手动添加

图片

将要查看的信号拖进波形图中

图片

我们可以观察到,计数器的最大值分别为4,9,9,与我们在testbench中设置的参数一致。输出信号的波形也达到了预期效果,先由灭到亮,再由亮到灭

分配管脚

图片

全编译后上板验证

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

    关注

    1603

    文章

    21329

    浏览量

    593299
  • led灯
    +关注

    关注

    22

    文章

    1554

    浏览量

    107037
  • PWM
    PWM
    +关注

    关注

    114

    文章

    4901

    浏览量

    209970
  • 脉冲信号
    +关注

    关注

    6

    文章

    333

    浏览量

    36439
  • 呼吸灯
    +关注

    关注

    9

    文章

    107

    浏览量

    42485
收藏 人收藏

    评论

    相关推荐

    #硬声创作季 #FPGA 明德扬 FPGA至简设计原理与应用52_1_PWM呼吸(PPT讲解)-3

    fpga呼吸
    水管工
    发布于 :2022年09月20日 12:30:33

    基于CPLD/FPGA呼吸效果实现(附全部verilog源码)(by 大飞)

    你的CPLD/FPGA里吧,瞬间实现你盼望已久的呼吸效果,赋予她(LED)生命的气息! 2. 晒干货例化时,仅需要按您的需求修改代码中带★号的参数ps. 只有一处需要修改哦亲
    发表于 11-19 22:58

    xilinx ISE 中异步FIFO ip的使用、仿真及各信号的讨论(图文教程)

    传输协议b2s (附全部verilog源码)2.脉冲信号正常与否的判断(附全部verilog源码)3.基于CPLD/FPGA呼吸效果实现(附全部verilog源码)4.“同频异宽”脉冲的选择(附
    发表于 07-16 15:09

    雾盈FPGA笔记之(一):基于FPGA呼吸简单实验程序(Verilog)

    ` 本帖最后由 西疆木 于 2016-8-29 10:37 编辑 基于FPGA呼吸简单实验程序(Verilog)雾盈 2016-7-26 1.呼吸
    发表于 07-28 19:03

    FPGA呼吸

    基于FPGA呼吸一、目标1、占空比(pwm)的理解。2、计数器的应用。3、分频的应用。二、要求四个LED从暗逐渐变亮,然后从亮逐渐变暗形成呼吸
    发表于 10-26 21:01

    基于CPLD/FPGA呼吸效果实现_呼吸源码_明德扬资料

    特效呼吸1功能概述顾名思义,特效呼吸是指在电路控制之下,LED灯光完成由灭到亮、由亮到灭的逐渐变化,感觉像是在呼吸一样。最原始的表现形式
    发表于 08-02 18:03

    至芯昭哥带你学FPGAFPGA_100天之旅_呼吸

    至芯昭哥带你学FPGAFPGA_100天之旅_呼吸
    发表于 08-22 09:54

    【雨的FPGA笔记】基础实践-------呼吸设计和实现

    本帖最后由 拾光333 于 2020-1-12 19:54 编辑 呼吸设计和实现内容一个周期为1s的呼吸,从熄灭到完全点亮一共需要1s。将1s分为1000个1ms作为
    发表于 01-12 19:50

    如何制作呼吸

    Stduino小白练习第三弹--制作呼吸2019/11/29 星期五作者:Astilbe问题:如何利用Stduino制作一个呼吸。我们之前已经学习过如何制作闪烁
    发表于 01-05 06:51

    STM32呼吸的原理是什么

    前段时间学习stm32的时候就做过呼吸实验,浏览了一些博客后,做下总结呼吸原理其实是利用pwm(脉冲宽度调节)技术,通过改变占空比来实现呼吸
    发表于 02-21 07:26

    基于FPGA呼吸灯设计

    呼吸灯主要是利用PWM的方式,在固定的频率下,通过调整占空比的方式来控制LED灯的亮度的变化,从而实现由暗渐亮再由亮渐暗的过程。
    的头像 发表于 09-27 11:43 1345次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>呼吸</b>灯设计