目錄基本原理
PWM的全稱是脈衝寬度調製(Pulse-width modulation),是通過將有效的電信號分散成離散形式從而來降低電信號所傳遞的平均功率的一種方式;
所以根據面積等效法則,可以通過對改變脈衝的時間寬度,來等效的獲得所需要合成的相應幅值和頻率的波形;
具體如下圖所示;
由上圖可知,脈衝寬度調製使用一個脈衝寬度會被調製的方波,並且波型的平均值會有所變化。
如果我們考慮一個周期為
當 是一個脈衝波,它的值在 是 而在 是
上式的描述可以變為:
以上公式可以在很多狀況下被簡化,當 及 。
從這裡可以看出,波型的平均值非常明顯地直接與佔空比 有關。
佔空比:
圖中存在三種佔空比狀態,25%,50%和75%佔空比狀態,不難發現,假設佔空比為D,則滿足:
其中是PWM的周期,通常和載波的周期相同;
PWM是如何實現?
PWM實現的原理是通過鋸齒波/三角波(載波)所需要合成的波形(調製波)進行比較,然後確定PWM所需要輸出的極性,通常是ON或者是OFF,因為一般都是作用到開關元器件上;如下圖所示;
振蕩器和比較器
振蕩器輸出的鋸齒波和參考值 進行比較,然後就可以輸出PWM波形了;
在matlab的simulink中搭建了一下仿真,具體如下圖所示;
simulink
最終輸出波形如下:
50%佔空比
這裡簡單說明一下:
鋸齒波(圖中橙色波形)最大為10,然後我希望輸出平均為5的波形(圖1中紅色的水平直線);那麼通過比較,當鋸齒波小於5時;PWM輸出低電平,即為OFF;
所以再換一個思路,如果我希望輸出一個電壓逐漸升高的波形呢,該如何設計呢?
其實很簡單,只要把需要調製的波形設置為斜坡輸出的波形就可以了,具體如下圖所示;
佔空比逐漸增大
可以看到,最終佔空比逐漸從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實現了一個呼吸燈的簡單程序。