2022年7月23日 星期六

STM32 使用DMA控制PWM輸出訊號

 這裡開發板MCU是使用"STM32F103C8T6"做實驗。 

1. SYS設定。

*Debug: Serial Wire

*勾選System Wake-Up


2. RCC設定。

High Speed Clock(HES): Crystal/Ceramic Resonator


3. TIM1設定。

Clock Source: Internal Clock

Channel1: PWM Generation CH1

設定好後,可以看到PIN腳PA8設定成PWM輸出。


注意: 如果PWM輸出訊號每次結束後,訊號要維持在低電位,要看PWM輸出訊號結束時,是在高電為還是低電位,來設定"CH  Polarity"為"Low" 或是 "High",因為"Low"、"High"這是一個訊號反向的設定。


4. 設定 Clock參數。

*PLL Source Mux: HSE
*System Clock Mux: PLLCLK
*HCLK(MHz): 72

設定好後,可以看到APB2 time clock(MHz) 等於72MHz,PWM的Tim Clock是以此為基礎。

5. TIM1 > Parameter Setting設定。

Prescaler(PSC - 16 bits value) : 72-1

Counter Period(AutoReload Register - 16 bits value): 1000

這裡設定Prescaler為72MHz~1MH範圍, 設定Counter Period為1000~1為頻率範圍,公式如下。

Tim Clock : 72MHz / 72 = 1MHz

Freq: 1MHz / 1000 = 1KHz 




6. TIM1 > DMA Setting設定。

按"Add" 增加DMA設定,DMA Request選擇"TIM1_CH1",Direction選擇"Memory To Peripheral", Mode設定成"Normal", Data Width都設定成"Half Word"。


7. 計畫管理設定。

*Project Name: 輸入計畫名稱
*Project Location: 設定存檔路徑
*Toolchain/IDE: MDK-ARM
設定完成按"GENERATE CODE"。

8. 建立一個矩陣,存放PWM高電位的時間,之前設定週期為1KHz,所以矩陣內參數100等於100us。

/* USER CODE BEGIN PD */

#define HPOT 10

uint16_t DataBuf[HPOT] = {900, 200, 300, 400, 500, 600, 700, 800, 900, 0};


9. 設定啟動PWM控制。

  /* USER CODE BEGIN 2 */

HAL_Delay(200);

        HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)&DataBuf, HPOT);


10. 設定PWM訊號輸出一次後關閉。

/* USER CODE BEGIN 0 */

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)

{

  HAL_TIM_PWM_Stop_DMA(htim, TIM_CHANNEL_1);

}

}


11. PWM輸出結果如下所示,Cursor量測出每一個週期為1KHz,共9個不同頻率的週期。

注意:不知道為什麼HPOT參數給10,最後指出來9個週期,因此矩陣最後一個參數我這裡直接設為0。








沒有留言:

張貼留言