# STM32 PWM [TOC] > TODO: 整理得好看一點 - 在每個脈衝週期內,在信號的一段時間輸出高電平,在剩餘的時間輸出低電平,達到類似輸出連續的高低電壓效果。 - **PWM輸出**:透過操控CCRx暫存器的數值,來控制IO輸出的高低電平時間 (佔空比)。 - **PWM輸入**:*待補...* ## 占空比計算 $$ Tclk = \frac{APB \ Tclk}{PSC} $$ - Tclk:TIMX運作時脈。 - APB Tclk:APB Bus運作時脈。 - PSC:預分頻係數,最高為65535。 > 假設APB Tclk為32,PSC為32,Tclk為32MHz / 32 = 1MHz。 $$ Freq = \frac{Tclk}{ARR} = \frac{\frac{APB \ Tclk}{PSC}}{ARR} $$ - Freq:PWM運作頻率。 - ARR:重載計數器數值,最高為65535。 > 假設Tclk為1MHz,ARR為100,Freq為1MHz / 100 = 10KHz。 $$ Duty = \frac{CCR_x}{ARR} * 100 $$ - Duty:PWM輸出占空比。 - CCRx:TIMx捕獲/比較暫存器 (Register)。 # PWM輸出 ## Steps 1. 除了TIM6/7,使用任何一個Timer皆可。(TIM6/7不是General-Purpose Timer) 2. Clock Source 選擇 Internal Clock。 - PWM通常會用較高頻的OSC當作時鐘來源 3. Channel 選擇 PWM Generation CHx。  4. 輸入PSC,Preload與調整其他選項。 - 記得要把數字減1  :::info **使用DMA輸出PWM** 1. 可以直接一次性的把值存至記憶體,再透過DMA輸出至IO口。 2. DMA Request選擇TIMx_CHx,Direction選擇Memory To Peripheral (記憶體到週邊),Mode選擇Normal。  ::: ## Code ### 呼吸燈 (漸變燈) - 宣告占空比與狀態 ```c uint8_t pwm_duty = 0; uint8_t pwm_state = 0; // 0: Low -> High / 1: High -> Low ``` - 設定初始占空比與啟動PWM輸出 ```c TIM2->CCR1 = 0; HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); ``` - 在While Loop中,改變PWM的佔空比,使得輸出不同的電壓。 - pwm_state = 0:佔空比增加。 - pwm_state = 1:佔空比減少。 ```c while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if (pwm_duty == 100) // 1: High To Low pwm_state = 1; else if (pwm_duty == 0) // 0: Low To High pwm_state = 0; else // Keep Duty Cycle pwm_state = pwm_state; pwm_duty = (pwm_state == 0) ? pwm_duty + 1 : pwm_duty - 1; TIM2->CCR1 = pwm_duty; HAL_Delay(10); } /* USER CODE END 3 */ ``` ### DMA控制 ```c uint8_t pwm_dma_duty[20] = {}; // 略過main...宣告佔空比 for(uint8_t i = 0; i < 20 ; i++) pwm_dma_duty[i] = i * 5; // 把陣列轉型成uint32_t,否則會因Data Type不同跳Warning HAL_TIM_PWM_START_DMA(&htim2, TIM_CHANNEL_1, (uint32_t *)pwm_dma_duty, 20); while (1) { // Do Smth... } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up