計時器怎麼產生 PWM?
預除頻器先把計時器時脈除以 PSC + 1,計數器再從 0 數到 ARR 後重新開始,所以一個 PWM 週期是 ARR + 1 個計數:
fPWM = f時脈 /((PSC + 1) × (ARR + 1))
計數器超過比較值 CCR 時輸出切換,所以佔空比是 CCR /(ARR + 1)。例如時脈 72 MHz、PSC = 71、ARR = 999 時,計數器跑 1 MHz,PWM 是 1 kHz;CCR = 250 就是 25% 佔空比。
中央對齊模式的計數器會數到 ARR 再數回來,一個週期是 2 × ARR 個計數:fPWM = f時脈 /((PSC + 1) × 2 × ARR),佔空比是 CCR / ARR。
頻率和解析度的取捨
時脈固定時,PWM 頻率越高,每個週期能分的階數就越少。ARR + 1 就是佔空比的階數,所以 PSC = 0 可以調得最細。第二個面板會先列出這個設定,再列出比較接近目標頻率、但解析度比較低的設定(如果有的話)。
| 時脈 | PWM | PSC | ARR | 階數 |
|---|---|---|---|---|
| 72 MHz | 1 kHz | 1 | 35999 | 36,000 |
| 72 MHz | 20 kHz | 0 | 3599 | 3,600 |
| 72 MHz | 50 Hz(伺服馬達) | 23 | 59999 | 60,000 |
| 16 MHz | 1 kHz | 0 | 15999 | 16,000 |
| 48 MHz | 25 kHz(電腦風扇) | 0 | 1919 | 1,920 |
| 170 MHz | 100 kHz | 0 | 1699 | 1,700 |
常見問題
為什麼是 PSC + 1 和 ARR + 1?
兩個暫存器都從 0 開始算。PSC = 0 是除以 1,ARR = 999 是從 0 數到 999 共 1000 個計數。所以 16 位元的 ARR 設 65535 時有 65,536 階。
STM32 的計時器時脈是多少?
計時器接在 APB 匯流排上。APB 預除頻大於 1 時,大部分 STM32 的計時器時脈是 APB 時脈的兩倍。例如 STM32F103 跑 72 MHz、APB1 是 36 MHz 時,TIM2~TIM4 還是 72 MHz。請以參考手冊或 CubeMX 的時脈樹為準。
AVR 和 Arduino 也能用嗎?
可以。AVR 的 Fast PWM 是 f = f時脈 /(N × (1 + TOP)),預除頻方式選「AVR 預除頻 N」,從清單選 N,ARR 填 TOP。8 位元的 Timer0、Timer2 請選 8 位元計時器。Phase Correct PWM 對應中央對齊的公式。Arduino Uno 的 5、6 腳預設 PWM 是 16 MHz /(64 × 256)≈ 977 Hz。
PWM 頻率該設多少?
LED 調光通常用幾百 Hz 到幾 kHz,避免看得到閃爍。馬達常用 20 kHz 以上,讓切換的聲音超出人耳範圍。模型伺服馬達要 50 Hz、脈寬 1~2 ms。