呼吸燈:本節(jié),我們將通過脈寬調(diào)制技術來實現(xiàn)“呼吸燈”,實現(xiàn)LED的亮度由最暗逐漸增加到最亮,再逐漸變暗的過程。 脈沖寬度調(diào)制(PWM:Pulse Width Modulation),簡稱脈寬調(diào)制。它是利用微控制器的數(shù)字輸出調(diào)制實現(xiàn),是對模擬電路進行控制的一種非常有效的技術,廣泛應用于測量、通信、功率控制與變換等眾多領域。
硬件說明
呼吸燈的設計較為簡單,我們使用12MHz的系統(tǒng)時鐘作為高頻信號做分頻處理,調(diào)整占空比實現(xiàn)PWM,通過LED燈LD1指示輸出狀態(tài)。


實現(xiàn)原理如上圖所示,脈沖信號的周期為T,高電平脈沖寬度為t,占空比為t/T。為了實現(xiàn)PWM脈寬調(diào)制,我們需要保持周期T不變,調(diào)整高電平脈寬t的時間,從而改變占空比。
結合呼吸燈的原理,整個呼吸的周期為最亮→最暗→最亮的時間,即t的值的變化:0→T→0逐漸變化,這個時間應該為2s

呼吸燈設計要求呼吸的周期為2s,也就是說LED燈從最亮的狀態(tài)開始,第一秒時間內(nèi)逐漸變暗,第二秒的時間內(nèi)再逐漸變亮,依次進行。
本設計中需要兩個計數(shù)器cnt1和cnt2,cnt1隨系統(tǒng)時鐘同步計數(shù)(系統(tǒng)時鐘上升沿時cnt1自加1)范圍為0~T,cnt2隨cnt1的周期同步計數(shù)(cnt1等于T時,cnt2自加1)范圍也是0~T,這樣每次cnt1在0~T的計數(shù)時,cnt2為一個固定值,相鄰cnt1計數(shù)周期對應的cnt2的值逐漸增大,我們將cnt1計數(shù)0~T的時間作為脈沖周期,cnt2的值作為脈沖寬度,則占空比 = cnt2/T,占空比從0%到100%的時間 = cnt2*cnt1 = T^2 = 1s = 12M個系統(tǒng)時鐘,T = 2400,我們定義CNT_NUM = 2400作為兩個計數(shù)器的計數(shù)最大值。

Verilog代碼
//********************************************************************
//>>>>>>>>>>>>>>>>>>>>>>>>>COPYRIGHTNOTICE<<<<<<<<<<<<<<<<<<<<<<<<<
//********************************************************************
//Filename:breath_led.v
//Modulename:breath_led
//Author:STEP//Description:
//
//--------------------------------------------------------------------
//CodeRevisionHistory:
//--------------------------------------------------------------------
//Version:|Mod.Date:|ChangesMade:
//V1.0|2017/03/02|Initialver
//--------------------------------------------------------------------
//ModuleFunction:呼吸燈
modulebreath_led(clk,rst,led);
inputclk;//系統(tǒng)時鐘輸入
inputrst;//復位輸出
outputled;//led輸出
reg[24:0]cnt1;//計數(shù)器1
reg[24:0]cnt2;//計數(shù)器2
regflag;//呼吸燈變亮和變暗的標志位
parameterCNT_NUM=2400; //計數(shù)器的最大值
period=(2400^2)*2=24000000=2s
//產(chǎn)生計數(shù)器cnt1
always@(posedgeclkornegedgerst)
begin
if(!rst)begin
cnt1<=13'd0;
end
elseif(cnt1>=CNT_NUM-1)
cnt1<=1'b0;
else
cnt1<=cnt1+1'b1;
end //產(chǎn)生計數(shù)器cnt2
always@(posedgeclkornegedgerst)
begin
if(!rst)begin
cnt2<=13'd0;
flag<=1'b0;
end
elseif(cnt1==CNT_NUM-1)begin//當計數(shù)器1計滿時計數(shù)器2開始計數(shù)加一或減一
if(!flag)
begin//當標志位為0時計數(shù)器2遞增計數(shù),表示呼吸燈效果由暗變亮
if(cnt2>=CNT_NUM-1)//計數(shù)器2計滿時,表示亮度已最大,標志位變高,之后計數(shù)器2開始遞減
flag<=1'b1;
else
cnt2<=cnt2+1'b1;
end
else
begin
if(cnt2<=0)//當標志位為高時計數(shù)器2遞減計數(shù)
flag<=1'b0; //計數(shù)器2級到0,表示亮度已最小,標志位變低,之后計數(shù)器2開始遞增
else
cnt2<=cnt2-1'b1;
end end
else
cnt2<=cnt2;//計數(shù)器1在計數(shù)過程中計數(shù)器2保持不變
end //比較計數(shù)器1和計數(shù)器2的值產(chǎn)生自動調(diào)整占空比輸出的信號,輸出到led產(chǎn)生呼吸燈效果
assign led=(cnt1 引腳分配如下: 脈寬調(diào)制是一種值得廣大工程師在許多應用設計中使用的有效技術,你也可以根據(jù)本節(jié)介紹的流水燈程序,實現(xiàn)RGB三色燈的呼吸。在下一小節(jié)我們會學習狀態(tài)機的使用方法:交通燈的設計。引腳分配
管腳名稱 clk rst led FPGA管腳 C1 L14 N13 小結
