【FPGA】实战之呼吸灯

一、呼吸灯的原理

呼吸灯,顾名思义,就是跟人的呼吸一样,是有一个过程的,由暗到亮,再由亮到暗的过程。
关于呼吸灯的原理就是利用PWM(脉冲宽度调制)的原理,不了解PWM没关系,用一句通俗易懂的话,来说,就是调节led灯的亮和灭在一定时间内的占比,一般一个led的正常亮灭的占比是各50%,但如果我调节亮灭占比,比如我给亮占比20%,给灭占比80%,就是比正常的led暗一点,反之就是比正常的亮一点,所以我们设计的思路就是控制这个占空比

二、设计思路

可以结合第四部分的波形图来设计
我们这里使用的简单的版本思路,不是常规的定义三个计数器1s,1ms,1us,而是利用和单片机一样的的预装载值和预比较值的思路。
这里有几个变量和常量,我解释一下
常量

  1. PRE是预装载值,相当于led亮暗的一次。
  2. ADD_DATA是预比较值的累加值,相当于你需要让led逐渐变亮,所需要的占空比也越来越大。

变量

  1. compare是预比较值,相当于占空比。
  2. flag是led变亮变暗的标志符,逐渐变亮记一次flag,然后达到最大占空比,此时led最亮了,需要开始变暗,就将flag反转。

led逐渐变亮,说明占空比是逐渐变大的,计数器累加到亮灭的一次,也就是预装载值,占空比累加,计数器与预比较值相比较,如果当前正好是逐渐变亮而且计数小于预比较值,就给高电平,让小灯亮,其余的就给低电平,相当于说亮少,暗多,逐渐变得亮多,暗少。
用一个大饼来比喻,大饼来分,我们自己来分配这个分的比例。

三、代码部分

工程创建的部分在我之前的博客里
【FPGA】实战之创建项目

这里直接上代码!

module breath_led #(parameter PRE = 100000,parameter ADD_DATA = 100)(

input                     clk,
input                     rst_n,

output   reg    [3:0]     led 
);

//预装载值
// parameter PRE = 8000;
// 1000000计数器位宽20
reg     [19:0]    cnt;
wire              add_cnt;
wire              end_cnt;

//预比较值
reg     [20:0]    compare;

// 从暗到亮和从亮到暗的标志信号flag
// 从暗到亮flag=1,从亮到暗flga=0
reg               flag;

// 计数器模块
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)begin
    cnt<=20'b0;
  end
  else if(add_cnt)begin
    if(end_cnt)begin
      cnt<=20'b0;
    end
    else begin
      cnt<=cnt+1'b1;
    end
  end
  else begin
    cnt<=cnt;
  end
end

assign  add_cnt=1'b1;
assign  end_cnt=add_cnt&&cnt==PRE-1;

//预比较值模块
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)begin
    compare<=0;
  end
  else if(compare>=PRE)begin
    compare<=0;
  end
  else if(end_cnt)begin
    compare<=compare+ADD_DATA;
  end
  else begin
    compare<=compare;
  end
end

//亮灭标志符flag模块
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)begin
    flag<=1'b0;
  end
  else if(compare>=PRE)begin
    flag=~flag;
  end
  else begin
    flag<=flag;
  end
end

//通过flag标志符以及计数器和预比较值的比较来控制呼吸灯模块
always @(posedge clk or negedge rst_n) begin
  if(!rst_n)begin
    led<=4'b0000;
  end
  // 如果是从暗到亮并且计数器小于预比较值  ,逐渐变亮
  else if((flag==1'b0&&cnt<compare)||(flag==1'b1&&cnt>compare))begin
    led<=4'b1111;
  end
  else begin 
    led<=4'b0000;
  end
end

endmodule

四、仿真验证

1.这段就是由暗到亮的波形图,可以看到高电平的占比是越来越大的
在这里插入图片描述
2.这段就是由亮到暗的波形图,可以看到高电平的占比是越来越小的
在这里插入图片描述

五、上板烧录验证

没问题
请添加图片描述
请添加图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值