設計背景
呼吸燈廣泛應用于手機之上,并成為各大品牌新款手機的賣點之一。如果手機里面有未處理的通知,比如說未接來電,未查收的短信等等,呼吸燈就會在控制之下完成由亮到暗的逐漸變化,感覺好像是人在呼吸,起到一個通知提醒的作用。
設計原理
關于呼吸燈設計實現的理論主要是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
+關注
關注
1630文章
21776瀏覽量
604678 -
脈沖
+關注
關注
20文章
897瀏覽量
95690 -
呼吸燈
+關注
關注
10文章
111瀏覽量
42772
原文標題:源碼系列:基于FPGA的呼吸燈設計(附源工程)
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論