基於FPGA的數位電路實驗8:PWM脈寬調製
2022-09-17由 硬禾學堂 發表于 林業
脈間和脈寬怎樣調整
今天終於要說到
脈衝寬度調製技術
了。聽到這一串由漢字組成的X%#@&*思密達,老司機不屑一顧揚長而去,新司機不明覺厲直接嚇走,於是就剩下我們這百來號低頭看手機的瓜友在這裡逛蕩了。
我們還是先從脈衝寬度調製的基礎說起。脈衝寬度調製,英文縮寫為:PWM(Pulse Width Modulation),是透過數字訊號實現對類比電路控制的一種非常有效的技術,常被廣泛應用於測量、通訊、功率控制與變換等眾多領域。
那麼PWM是如何工作的?
我們知道,數位電路只能產生高電平(1)或低電平(0),在小腳丫上也就意味著3。3V和0V。那麼如果我們的應用恰好在這之間怎麼辦?比如,將3。3V直接連到LED上會導致LED燈很亮。如何將LED燈調暗呢?當然,最簡單的辦法就是直接串聯一個限流電阻但這樣一來,限流電阻就需要不斷產生功耗,而這個功耗實際上是完全浪費掉的。
無非就是調節LED的亮度而已,難道就沒有其他更好的辦法了嗎?當然有,用我們今天學習的PWM就可以輕鬆實現。在進一步探討點亮LED之前,我們先透過圖1瞭解一些基本的引數:
圖1
圖1中,脈衝訊號的週期為T,高電平寬度為t。如果我們將t/T定義為佔空比,佔空比就是2/3,因為高電平的寬度佔了整個週期的2/3。在圖1中我們還可以看到一條紅色虛線,畫在了脈衝高度2/3的位置。這條虛線實際上就對應著最終的有效值。那麼如何在FPGA上生成PWM訊號呢?
我們還是習慣看圖說話,請看圖2。假如我們有一個鋸齒波,然後在鋸齒波上設定一個閾值(黑色水平虛線),凡是大於該閾值時輸出均為高電平,反之則為低電平,這樣我們是不是就得到一個PWM訊號呢?如果我們想調整它的佔空比,那麼調節閾值的高低就可以了。在本例中,閾值線越低佔空比越高。
圖2
如果把上面的描述再抽象化一下,就可以畫出圖3的模組框圖。鋸齒波實際上就可以用計數器生成,閾值就是一個數值而已,比較器是用來生成最後輸出高低電平用的。
圖3
有了設計思路之後,我們來看一下最終程式碼。
module pwm (PWM_out, clk, reset);
input clk, reset;
output reg PWM_out;
wire [7:0] counter_out; //計數器的8位寬儲存,可以最多數128次時鐘的嘀嗒
parameter PWM_ontime = 32; //閾值設在32,對應25%的佔空比
always @ (posedge clk) begin //比較器
if (PWM_ontime > counter_out)
PWM_out <= 0;
else
PWM_out <= 1;
end
counter counter_inst( //呼叫計數器
。clk (clk),
。counter_out (counter_out),
。reset(reset)
);
endmodule
module counter(counter_out,clk,reset); //計數器模組程式碼
output [7:0] counter_out;
input clk, reset;
reg [7:0] counter_out;
always @(posedge clk)
if (reset) //如果沒有按reset,則計數器清零
counter_out <= 8‘b0;
else //如果按下reset,則計數器開始計數
counter_out <= counter_out + 1;
endmodule
在程式碼中,我們設定的計數器位寬是8位,也就是每128次後自動重新計數。所以,該計數器的最大頻率也就是12MHz/128=93。75KHz。圖3中可以看出,PWM訊號的頻率和計數器的頻率相同,因此也是93。78KHz。
試想一下,LED現在正以超過每秒9萬次的速度閃爍,肉眼是完全分辨不出來的。那麼閃爍過程中,亮/滅的比值越大,LED的視覺發光效果就越強,反之則越弱。我們最後將上述程式匯入小腳丫中,並透過調節閾值來觀察小腳丫上的LED發光強度的變化。
現在思考題來了:
1。 已知小腳丫的板載LED的正向點亮電壓為1。8V
2。 已知小腳丫的高電平為3。3V,低電平為0V
3。 現在我們將一個佔空比為10%的PWM訊號接到LED上,能不能看到LED點亮?
答案:能
回答錯誤的你一定非常不服,於是從積灰的古董箱裡翻出來寶刀已老的萬用表,調成直流電壓測量模式後一測發現:沒錯啊!就是0。33V,和預期的3。3*10%=0。33V一樣!那怎麼可能還會點亮,一定是LED壞了,哦不,是萬用表壞了,好像也不是…難道是小腳丫壞了?
NO,NO,NO,請不要告訴我小腳丫壞了。