FPGA开发——呼吸灯实现

前言

以下思路及代码均为本人学习总结,其中有不妥之处请见谅!若出现bug大家一起探讨!

一、PWM

        脉冲宽度调制技术(Pulse Width Modelation,PWM)是利用微处理器/FPGA的数字输出对模拟电路进行控制的一种有效技术,其广泛应用于测量、通信、功率控制与变换等众多领域。PWM数字信号从处理器到被控系统都采用数字形式,无需进行数模转换。通俗来说,PWM是连续的、具有一定比例占空比的脉冲信号,可以通过控制占空比来对其进行改变。简单来说,可以认为PWM就是一种方波。

 二、原理

原理:呼吸灯的控制可以通过控制占空比来控制LED灯的亮度。
        假设刚开始时占空比为1%,慢慢的占空比为2%、3%、4%.......56%、57%......98%、99%、100%。这就是LED灯亮的一个过程,我们可以让占空比为1%时,令LED灯亮,其余的部分让LED灭,慢慢的占空比越来越大,亮的部分也越来越多,这就是一个由灭到亮的一个过程。
        假设刚开始时占空比为100%,慢慢的占空比为99%、98%、97%.....4%、63%.....2%、1%、0%。这就是LED灯灭的一个过程,我们可以让占空比为99%时,令LED灯灭,其余的部分让LED亮,慢慢的占空比越来越小,灭的部分也越来越多,这就是一个由亮到灭的一个过程。

三、时序图

 四、代码实现

`timescale 1ns / 1ps

module led_breathe
#
(
    parameter TIME_1ms = 50_000,//1ms
    parameter TIME_1us = 50    ,//1us 单位:clk
    parameter T        = 2000   //呼吸灯周期
)
(
    input            clk       ,
    input            rst_n     ,
    output  reg   [3:0] led     
);

reg [31:0] ms;      //记录ms加了多少次
reg [31:0] us;      //记录us加了多少次
reg [31:0] cnt_ms;  //记录ms的时间
reg [31:0] cnt_us;  //记录us的时间

reg flag;//0灭 1亮

//1ms计时器
always@(posedge clk)
    if(!rst_n)
        cnt_ms <= 0;
    else if(cnt_ms < TIME_1ms)
        cnt_ms <= cnt_ms + 1;
    else
        cnt_ms <= 0;    
        
//ms计数器
always@(posedge clk)
    if(!rst_n)     
        ms <= 0;
    else if(cnt_ms == TIME_1ms - 1) begin
        if(ms == T - 1)
            ms <= 0;
        else
            ms <= ms + 1;
    end
    else
        ms <= ms;
 
 //1us计时器
always@(posedge clk)
    if(!rst_n)
        cnt_us <= 0;
    else if(cnt_us == TIME_1us - 1)
        cnt_us <= 0;
    else
        cnt_us <= cnt_us + 1;  
//us计数器
always@(posedge clk)
    if(!rst_n)
        us <= 0;
    else if(cnt_us == TIME_1us - 1) begin
        if(us == T - 1)
            us <= 0;
        else
            us <= us + 1;
    end
    else
        us <= us;
 LED输出  
always@(posedge clk)
    if(!rst_n)
        flag <= 0; 
    else if(cnt_ms == TIME_1ms - 1 && ms == T -1)
        flag <= ~flag;
    else 
        flag <= flag;

always@(posedge clk)
    if(!rst_n)
        led <= 4'b0000;
    else if(flag == 0)begin
        if(ms > us)
            led <= 4'b1111;
        else if(ms <= us)
            led <=4'b0000;
    end
    else if(flag == 1)begin
         if(ms > us)
            led <= 4'b0000;
        else if(ms <= us)
            led <=4'b1111;
    end    
endmodule

五、总结

        呼吸灯实现方法有多种,本人使用了一种比较便于实现和理解的方式供大家参考。给大家再提供一种状态机写法的状态转换图供大家学习使用。

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值