FPGA实战----点灯大师(2)led呼吸灯

点灯大师(2)led呼吸灯

上一章学习了流水灯跑马灯,接下来学习如何编写呼吸灯。



前言

呼吸灯的应用非常广泛,一些手机充电时顶上一亮一亮的就是呼吸灯。简单来说呼吸灯就是模仿人类呼吸的动作,吸入呼出,变为由亮变暗,由暗变亮。


一、呼吸灯原理

呼吸灯就是利用PWM(脉冲宽度调制)的原理,不了解PWM没关系,简单来说,就是调节led灯的亮和灭在一定时间内的占比,一般一个led的正常亮灭的占比是各50%,但如果我调节亮灭占比,比如我给亮占比20%,给灭占比80%,就是比正常的led暗一点,反之就是比正常的亮一点,所以我们设计的思路就是控制这个占空比。
在由计数器产生的固定周期的 PWM 信号下,如果其占空比为 0,则 LED 灯不亮;如果其占空比为100%,则 LED 灯最亮。所以将占空比从 0 到 100%,再从 100%到 0 不断变化,就可以实现 LED 灯的“呼吸”效果。
调解占空比变亮度

二、代码

1.呼吸灯

代码如下

/*
 * @Projcet: breathe_led
 * @Author: Yang.
 * @Date: 2023-09-30 08:48:22
 * @LastEditors: Yang.
 * @LastEditTime: 2023-09-30 19:38:59
 */
//---------<模块及端口声名>------------------------------------------------------
module breathe_led( 
    input   wire       clk        ,
    input   wire       rst_n      ,
    output  reg [3:0]  led_out     
);

//---------<参数定义>--------------------------------------------------------- 
    parameter TIME_2US = 6'd99   ;
    parameter TIME_2MS = 10'd999 ;
    parameter TIME_2S  = 10'd999;


reg [6:0] cnt_2us;//0-99需要7位
wire	  add_cnt_2us	;
wire	  end_cnt_2us	;
reg [9:0] cnt_2ms;//0-999需要10位
wire   	  add_cnt_2ms	;
wire	  end_cnt_2ms	;
reg [9:0] cnt_2s ;//0-999需要10位
wire	  add_cnt_2s	;
wire	  end_cnt_2s	;
reg       flag ;//FLAG LED亮灭的标志


//****************************************************************
//2us计数器
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
		cnt_2us <= 'b0;
    end
	else if(add_cnt_2us)begin 
    if(cnt_2us == TIME_2US)begin
		cnt_2us <= 'b0;
    end
	else begin	
		cnt_2us <= cnt_2us + 1'b1;
    end	
    end
end

assign add_cnt_2us = 'd1;
assign end_cnt_2us = add_cnt_2us && cnt_2us == TIME_2US ;

//****************************************************************
//20ms计数器
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
		cnt_2ms <= 10'b0;
    end
	else if(add_cnt_2ms)begin 
    if(end_cnt_2ms)begin
		cnt_2ms <= 10'b0;
    end
	else begin
		cnt_2ms <= cnt_2ms + 1'b1;
    end
    end	
end
assign add_cnt_2ms = end_cnt_2us;
assign end_cnt_2ms = add_cnt_2ms && cnt_2ms == TIME_2MS ;

//****************************************************************
//2s计数器
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
		cnt_2s <= 10'b0;
    end
	else if(add_cnt_2s)begin
       if(end_cnt_2s)begin
		cnt_2s <= 10'b0;
    end
	else begin
		cnt_2s <= cnt_2s + 1'b1;
    end
    end	
end
assign add_cnt_2s = end_cnt_2ms;
assign end_cnt_2s = add_cnt_2s && cnt_2s == TIME_2S ;

//****************************************************************
flag计数器标志信号
//****************************************************************
 always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        flag <= 1'b0;  
    end
    else if(end_cnt_2s)begin
        flag <= ~flag; 
    end
 end

//****************************************************************
led:负责呼吸灯控制
//****************************************************************
always@(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
		led_out <= 4'b0000;
    end
    else if (flag) begin
        led_out <= (cnt_2s > cnt_2ms) ? 4'b1111 :4'b0000 ;
    end
    else begin
        led_out <= (cnt_2s > cnt_2ms) ? 4'b0000 : 4'b1111 ;
    end
end

endmodule

2.仿真

代码如下:

`timescale  1ns/1ns

module tb_led();
  reg        clk;
  reg        rst_n;
  wire [3:0] led_out;

  breathe_led u_breathe_led (
    .clk       (clk),
    .rst_n     (rst_n),
    .led_out    (led_out)
  );
  defparam  u_breathe_led.TIME_2S = 10;
  defparam  u_breathe_led.TIME_2MS= 10;
  defparam  u_breathe_led.TIME_2US= 5;
  always #5 clk = ~clk;

  initial begin
    clk = 0;
    rst_n = 0;
    #10 
    rst_n = 1;

  end
endmodule

总结

1、仿真结果

仿真结果
从仿真中可以看出led灯珠亮(1111)的时间越来越短一个周期,也就是越来越暗。

2、上板结果

点灯大师(2)---led呼吸灯

其实呼吸灯没什么可以大写特写的东西,占空比调解而已。
led玩出来的花样差不多了。
手里还有一个8*8的WS2812B的led灯板,不过那个现在发还太早,等再往深学几天再发啊。

博客上传的工程都在百度网盘,有压缩包也有整个文件,可以自行下载。
链接:https://pan.baidu.com/s/1lQqqWZXfb3i6XHwkKf52zg
提取码:yang

接下来数码管、蜂鸣器、按键消抖陆续就接上了,加油!!!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值