以TIMER為主要觀察源,使用TIMER觸發ADC,透過DMA結合,同時觀察ADC中斷副程式,進而延伸不同領域應用。
STM32G4系列ADC支援多樣的觸發取樣方式,可以利用Timer和GPIO做觸發。
以STM32G431為例,除了軟體觸發外還支援下列來源的觸發。
這個範例,採用TIMER3 CC4作為ADC觸發訊號觀察。
在STM32CubeMX中,首先對ADC做設置如下。
先建立ADC通道,再開啟DMA通道,透過DMA可使ADC完全觸發於被動狀態。
設定ADC相關功能(另外說明),與開啟DMA。
以TIMER3 CC4作為ADC觸發訊號觀察,設定對應選項。
ADC與DMA結合設定完成,接下來只需將TIMER完成設定即可完成此次實驗與觀察目的。
設定Timer 3 Channel 4為PWM,因為不需要從硬體pin腳輸出波形。
只需要產生對應的事件event,所以設置為PWM Generation No Output。
若需要觀察TIME3 CH4對應波形,也可選擇PWM Generation CH4,觀察後再關閉即可。
此次範例設計1KHz PWM輸出,對應主頻170MHz,TIMER基礎設定如下。
完成ADC與TIMER的設定後,開始 Generation code 之後回到maim.c完成最後步驟。
小記
每次使用CubeMX設定相關條件時,都認為似乎很容易,但其實基礎設定就僅如此,較困難的部分是進階用法,需要非常熟悉CubeMX裡面相關設定代表意義,才能夠如願完成進階功能與開發。難怪前輩說最好還是要全部熟悉一遍。
然後在main.c中,新增程式碼如下。
暫存器設定
/* USER CODE BEGIN PV */
uint16_t Value_PWMDuty = 0;
uint16_t Data_adc[10];
/* USER CODE END PV */
記得下指令啟用ADC與TIMER。
若有另外啟用中斷副程式,則下面程式需要符合為中斷副程式的指令。
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim3);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)Data_adc,1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
/* USER CODE END 2 */
另外啟用GPIO,觀察PWM波形與時序關係。
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
HAL_GPIO_TogglePin(TEST_GPIO_Port, TEST_Pin);
}
/* USER CODE END 4 */
HAL_ADC_Start_DMA為啟動ADC DMA傳輸,取樣傳輸1次後結束。
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);為啟動Timer 3 Channel 4
當Timer啟動後才會觸發ADC取樣,因設定取樣完1次後,會自動呼叫HAL_ADC_ConvCpltCallback這個callback函式,在此函數內使用GPIO High / Low動作,接到示波器量測。
在主迴圈while (1)中,設定 Value_PWMDuty = 400,由先前CubeMX設定計算,應可由示波器得到PWM duty為10%的波形
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Value_PWMDuty = 400;
HAL_Delay(250);
TIM3->CCR4 = Value_PWMDuty;
}
/* USER CODE END 3 */
如main.c所設定,圖中顯示GPIO High / Low動作達到預期1KHz與10% duty的條件。
可得知ADC已依照設定的取樣率工作。
若將Value_PWMDuty持續修改參數,亦可得到對應的duty設定。
為了確認此GPIO所對應PWM是否正確,將由CubeMX增加設定TIMER3 CH2 為PWM output,以實際腳位pin12觀察兩個PWM關係。
由上視窗可以看見,兩PWM波形幾乎是同步運作。
但實際放大後發現,兩PWM中間存在延遲,就是所謂TIMER觸發ADC而DMA取樣1次的時間。
回到CubeMX中設定ADC1的參數Sampling Time,將會影響ADC轉換時間,而影響DMA後續觸發延遲。
更進一步發現,當Value_PWMDuty設定為過小,則由HAL_ADC_ConvCpltCallback函數觸發的GPIO將異常。
此部份認為,因為TIMER3 CH2的duty已經小於ADC轉換時間,所以只能抓到一次觸發。
小記
本篇目的不是在ADC部分,而是如何結合TIMER觸發ADC,同時可以觸發中斷副程式,使得可以在中斷副程式裡添加要實現的功能,但發現當設定duty過小於ADC轉換時間時,就會出現異常。
結論判定此方式並不完全適合目前所需用功能
若此文章對您有幫助或學習,歡迎加入likecoin讚賞公民,下方連結點擊like支持~
本文參考