设计背景
呼吸灯广泛应用于手机之上,并成为各大品牌新款手机的卖点之一。如果手机里面有未处理的通知,比如说未接来电,未查收的短信等等,呼吸灯就会在控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸,起到一个通知提醒的作用。
设计原理
关于呼吸灯设计实现的理论主要是PWM有关知识。PWM(Pluse Width Modulation)脉冲宽度调制,是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。并广泛应用在从测量、通信、功率控制与变换及LED照明等许多领域中。顾名思义,就是占空比可调的信号,那么什么是占空比呢?
占空比(Duty Cycle or Duty Ratio),可以解释为,在一脉冲序列中(方波),正脉冲序列的持续时间与脉冲总周期的比值。也可理解为,电路释放能量的有效时间与总释放时间的比值。
PWM是怎样实现调光呢?想要调节LED的亮度变化,实则是调节控制流经LED的电流。电流增大则LED亮度增强,反之减弱。但由于电流为模拟信号,所以这时就用到了PWM。正如下图所示:
使用一系列等幅不等宽的脉冲来代替一个正弦波,脉冲的宽度根据正弦波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时钟
设计代码
设计模块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仿真图:
仿真中可以看到点亮led等高电平在不停的增高,然后会降低,通过验证我们的设计是正确的。
END
-
FPGA
+关注
关注
1638文章
21856浏览量
609431 -
脉冲
+关注
关注
20文章
899浏览量
96196 -
呼吸灯
+关注
关注
10文章
111浏览量
42913
原文标题:源码系列:基于FPGA的呼吸灯设计(附源工程)
文章出处:【微信号:HXSLH1010101010,微信公众号:FPGA技术江湖】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
【瑞萨RA2L1入门学习】01. PWM 呼吸灯
ADS1298R外部呼吸模式和内部呼吸模式的区别?
基于FPGA的VGA驱动设计(附源工程)

ADS1292R的呼吸阻抗检测功能在运动模式下是否有办法能提取出准确的呼吸信号?
ADS1292R采集呼吸波采样率越高,采样得到的呼吸波幅度越低,为什么?
AMC1303E输出接的Altera FPGA,通过FPGA解码后输出总是突然来个变异的大数据,为什么?
多平台FPGA工程快速移植与构建

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

评论