本文將帶你了解PWM。我們將學習PWM的基本原理與分類,PWM如何實現,以及程序實現。如果覺得不錯,歡迎關注、分享、收藏、點贊。希望能幫助到大家,如有錯誤敬請指出,謝謝!
目錄
- 基本原理
- PWM是如何實現?
- 分類
- 程序實現
- 總結
一、基本原理
PWM的全稱是脈沖寬度調制(Pulse-width modulation),是通過將有效的電信號分散成離散形式從而來降低電信號所傳遞的平均功率的一種方式。
所以根據面積等效法則,可以通過對改變脈沖的時間寬度,來等效的獲得所需要合成的相應幅值和頻率的波形。
具體如下圖所示:
由上圖可知,脈沖寬度調制使用一個脈沖寬度會被調制的方波,并且波型的平均值會有所變化。
因為不支持自動解析latex公式,又不想重新敲公式,下面文字我直接復制為圖片了;
占空比:
圖中存在三種占空比狀態,25%
,50%
和75%
占空比狀態,不難發現,假設占空比為D
,則滿足:
其中是PWM的周期,通常和載波的周期相同;
二、PWM是如何實現?
PWM實現的原理是通過鋸齒波/三角波(載波)所需要合成的波形(調制波)進行比較,然后確定PWM所需要輸出的極性,通常是ON
或者是OFF
,因為一般都是作用到開關元器件上;如下圖所示;
振蕩器和比較器
振蕩器輸出的鋸齒波和參考值 進行比較,然后就可以輸出PWM
波形了;
在matlab
的simulink
中搭建了一下仿真,具體如下圖所示;
simulink
最終輸出波形如下:
50%占空比
這里簡單說明一下:
- 鋸齒波(圖中橙色波形)最大為
10
,然后我希望輸出平均為5
的波形(圖1中紅色的水平直線); - 那么通過比較,當鋸齒波小于
5
時;PWM輸出低電平,即為OFF
; - 當鋸齒波大于
5
時,PWM輸出高電平,即為ON
;
所以再換一個思路,如果我希望輸出一個電壓逐漸升高的波形呢,該如何設計呢?
其實很簡單,只要把需要調制的波形設置為斜坡輸出的波形就可以了,具體如下圖所示;
占空比逐漸增大
可以看到,最終占空比逐漸從0%
增大到100%
;
然后我們繼續想,能不能調制出其他的波形,比如調制一個正弦波sin wave
,那也就是我們常說的SPWM
,其實是可以的,具體如下圖所示;
SPWM
三、分類
參考STM32中PWM的配置,根據載波波形的形狀,假設三角波最大值是10,那么它的變化過程可能存在以下兩種情況:
- 完整周期包括兩個過程,先遞增,再遞減:增加增加減少減少,這種也叫中央對齊PWM;
- 完整周期只有遞增過程:增加增加;
中央對齊PWM
脈沖波的中心將會被固定在時間窗格的中心,同時脈沖波的兩邊可以移動,使得波的寬度被延伸或壓縮,具體如下圖所示;
中央對齊PWM
另一種類型的PWM脈沖波形如下圖所示;
四、程序實現
現在的MCU
大部分都自帶硬件PWM
發生器,即配置好相應的寄存器,就能直接產生PWM
,下面的例子基于NUCLEO-F767ZI
,通過cubemx
配置了三路PWM
輸出,然后實現了呼吸燈的效果;
int main(void)
{
HAL_Init();
MX_GPIO_Init();
MX_TIM4_Init();
MX_TIM3_Init();
MX_TIM12_Init();
int32_t time_stamp = 0;
int32_t time_stamp_old = 0;
int32_t ccr_val = 0;
uint8_t add_flag = 1;
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
while (1)
{
time_stamp = HAL_GetTick();
if(time_stamp - time_stamp_old > 5){
time_stamp_old = time_stamp;
if(add_flag){
ccr_val+=25;
if(ccr_val >= 0xFFFF){
ccr_val = 0xFFFF;
add_flag = 0;
}
}else{
ccr_val-=25;
if(ccr_val <= 0){
add_flag = 1;
ccr_val = 0;
}
}
TIM4->CCR2 = ccr_val;
TIM12->CCR1 = ccr_val;
TIM3->CCR3 = ccr_val;
}
}
}
整體效果如下:
呼吸燈
通過示波器看其中的一路PWM
輸出的占空比也是隨時間變化;
PWM變化情況
五、總結
本文簡單介紹了PWM的原理,以及如何產生PWM,可以通過鋸齒波作為載波和調制波經過比較強,產生相應的PWM輸出波形,最后結合STM32實現了一個呼吸燈的簡單程序。