一、背景
步進電機在每個PWM信號的上升沿時轉動一步,同時要求在每移動一步之前的一段時間或者之後的一段時間進行ADC採樣,這裏用的是內部ADC,如下圖1洋紅色的上升沿觸發步進電機轉動,黃色的上升沿觸發AD採樣,這裏注意STM32的AD的外部觸發只能是上升沿,在《STM32中文參考手冊》中,有關於這部分的內容如圖2,寫本文時用的是STM32VET6。
圖1
圖2
另外ADC的外設框圖如下圖3所示:
圖3
本文采用的是ADC1的通道13(PC3)採集外部模擬信號。TIM4爲主模式控制PWM的頻率,其通道2輸出PWM,即配置爲PWM Generation CH2(PD13);通道4觸發ADC,也配置成PWM模式,即PWM Generation CH4,其實在我的項目中通道4的引腳有其他用途,本想配置成PWM Generation CH4 No Output,但是這樣配置以後沒法觸發ADC進行採樣,猜測是這種模式不只是不從外部引腳輸出,而且內部也沒有輸出,我最後的做法是將該IO(PD15)的複用模式只能強制配置成了普通推輓輸出。TIM5爲從模式接收TIM4的ITR2觸發源,用於控制PWM的個數。
二、引腳設置
AD的引腳配置如下圖4所示,只選擇了IN13。
圖4
定時器的引腳選擇如下,注意這裏TIM5的Salve MOde及Trigger Source的選擇:
圖5
三、AD參數設置
AD的參數設置如下,注意要正確選擇外部觸發源,這裏選擇的是Timer 4 Capture Compare 4 event
AD的DMA設置如下,這裏嘗試了Mode不管是Normal還是Circular都可以,暫不知本文的應用中設置不同是否有影響:
四、TIM4參數設置
TIM4的參數設置如下:
五、TIM5參數設置
TIM5配置如下,TIM5需要使能全局中斷:
六、代碼
啓動AD開始轉換:HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adcData,1000);
啓動定時器輸出PWM同時觸發AD轉換:
htim5.Instance->ARR = 1000; //演示直接這樣改PWM的個數
HAL_TIM_Base_Start_IT(&htim5);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
在定時器5的中斷回調裏關閉PWM及AD的觸發
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_4);
HAL_TIM_Base_Stop(&htim5);
在AD傳輸完成中斷裏處理數據:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc == &hadc1)
{
//AD傳輸完成,可以開始處理數據了
}
}
注意調用HAL_ADC_Start_DMA時傳入的傳輸個數不能比PWM的個數多,否則一次啓動將填不滿想要的個數也不好觸發中斷,可以用宏定義把它們設置成一致。