3.13. 使用 PWM 與 RC 濾波器產生類比訊號¶
ADC 會讀取接腳上的電壓。相反的做法——在接腳上產生介於 0 V 與 Vcc 之間的中間電壓——則比較困難,因為 GPIO 輸出只知道如何驅動它的兩條電源軌。標準的替代做法是以足夠快的速度在兩條電源軌之間切換接腳,使你真正在意的平均電壓正好是想要的值。
3.13.1. 脈衝寬度調變¶
脈衝寬度調變(pulse-width modulation,PWM)訊號是一種固定頻率的方波,其高態時間——也就是每個週期中停留在 Vcc(而非接地)的比例——由軟體設定。這個比例就是工作週期。波形的平均電壓等於工作週期乘以 Vcc:
V_avg = duty × Vcc
25 % 的工作週期平均為 Vcc / 4;50 % 的工作週期平均為 Vcc / 2;75 % 的工作週期平均為 3 × Vcc / 4。
工作週期分別為 25 %、50 % 與 75 % 的 PWM。平均電壓會跟隨工作週期變化。¶
頻率在設定 PWM 時就已決定;工作週期則是軟體可以即時改變的部分。machine.PWM 類別封裝了一個產生波形的硬體計時器通道,無需 CPU 介入——一旦設定完成,訊號就會以所選的頻率與工作週期持續輸出,直到被改變為止。
3.13.2. machine.PWM 類別¶
用接腳以及初始頻率與工作週期來建構一個 PWM 實例:
from machine import PWM, Pin
pwm = PWM(Pin("P7"), freq=20_000, duty_u16=32768)
這會在 P7 上以 50 % 工作週期啟動一個 20 kHz 的方波。有兩個方法可以即時改變輸出:
pwm.duty_u16(16384) # change to 25 % (16384 / 65535)
pwm.freq(5_000) # change to 5 kHz
duty_u16() 接受一個無號 16 位元整數,0 對應到「永遠為低態」,65535 對應到「永遠為高態」。freq() 則以赫茲為單位設定載波頻率。
備註
同一個硬體計時器上的每個 PWM 通道共用相同的頻率。在某個通道上呼叫 freq() 會改變連接到該計時器的所有其他通道。當輸出必須以不同頻率運作時,請使用不同計時器的通道。
當不再需要輸出時,呼叫 deinit() 以釋放該計時器通道。
3.13.3. 使用 RC 低通濾波器取平均¶
原始的 PWM 並不是平滑的電壓;它是一個方波,我們想要的是它的平均值。為了取出該平均值,請讓 PWM 通過一個低通濾波器——也就是 去彈跳 中用於開關去彈跳的同一組電阻與電容組合。
PWM 通過 RC 低通濾波器:電容將方波平均成一個與工作週期成正比的直流電壓。¶
濾波器的截止頻率——也就是它所通過的頻率與所阻擋的頻率之間的分界——由與去彈跳電路時間常數相同的 RC 乘積決定:
f_c = 1 / (2π × R × C)
為了讓濾波器能從 PWM 輸入取出乾淨的直流電壓,截止頻率必須遠低於 PWM 頻率本身。直流分量(頻率為 0)會原封不動地通過;PWM 的基波諧波(位於 PWM 頻率處)則大約被衰減 f_c / f_PWM。1 / 200 的比值可將輸出端的殘餘漣波降至約輸入擺幅的 0.5 %。
對於緩慢變化的設定點,一個合理的起點是:
PWM 頻率
f_PWM = 20 kHz——遠高於音頻,且計時器易於乾淨地產生。濾波器數值
R = 1.6 kΩ、C = 1 µF——得到f_c = 1 / (2π × 1.6 kΩ × 1 µF) ≈ 100 Hz。
載波處 200 倍的抑制會將 PWM 的完整擺幅降至 V_out 處約 Vcc / 200 的殘餘漣波——在 3.3 V 時約為 16 mV。
兩點實務注意事項:
濾波器的輸出阻抗大致為
R。任何抽取電流的下游負載都會讓R與該負載組成一個分壓器,使V_out被拉到低於理想平均值,這與 使用 ADC 讀取類比訊號 頁面上的分壓器情況完全相同。請饋入 ADC 接腳或高阻抗緩衝器,而不是會吸取數毫安培的負載。當工作週期改變時,電容約需
5 × R × C ≈ 8 ms才能穩定;V_out會比工作週期設定值落後這麼多時間。若設定點需要更快更新,請提高截止頻率(較小的R或C)並接受較多的漣波。