iT邦幫忙

0

[Q1][STM32G4系列] TIMER觀察 - 使用TIMER觸發ADC,透過DMA方式結合

前言

以TIMER為主要觀察源,使用TIMER觸發ADC,透過DMA結合,同時觀察ADC中斷副程式,進而延伸不同領域應用。

內容

STM32G4系列ADC支援多樣的觸發取樣方式,可以利用Timer和GPIO做觸發。
以STM32G431為例,除了軟體觸發外還支援下列來源的觸發。

https://ithelp.ithome.com.tw/upload/images/20211018/201430211kFf9g5lDx.jpg

_ / CubeMX設定ADC \

這個範例,採用TIMER3 CC4作為ADC觸發訊號觀察。
在STM32CubeMX中,首先對ADC做設置如下。


先建立ADC通道,再開啟DMA通道,透過DMA可使ADC完全觸發於被動狀態。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021miC8kKlw8O.jpg
https://ithelp.ithome.com.tw/upload/images/20211018/20143021aFvxpLtJKj.jpg


設定ADC相關功能(另外說明),與開啟DMA。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021QV89EYGhbe.jpg

以TIMER3 CC4作為ADC觸發訊號觀察,設定對應選項。

  1. 外部觸發來源更改為Timer 3 Capture Compare 4 event
  2. 並選擇上下緣觸發

https://ithelp.ithome.com.tw/upload/images/20211018/20143021Y5oROVYo0X.jpg

ADC與DMA結合設定完成,接下來只需將TIMER完成設定即可完成此次實驗與觀察目的。


__ / CubeMX設定TIMER \

設定Timer 3 Channel 4為PWM,因為不需要從硬體pin腳輸出波形。
只需要產生對應的事件event,所以設置為PWM Generation No Output。
若需要觀察TIME3 CH4對應波形,也可選擇PWM Generation CH4,觀察後再關閉即可。
https://ithelp.ithome.com.tw/upload/images/20211018/201430219bPAcqixBk.jpg


此次範例設計1KHz PWM輸出,對應主頻170MHz,TIMER基礎設定如下。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021a5qNqOWxZE.jpg

完成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已依照設定的取樣率工作。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021HUKR8548DR.png

若將Value_PWMDuty持續修改參數,亦可得到對應的duty設定。


為了確認此GPIO所對應PWM是否正確,將由CubeMX增加設定TIMER3 CH2 為PWM output,以實際腳位pin12觀察兩個PWM關係。

由上視窗可以看見,兩PWM波形幾乎是同步運作。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021iwLfQSlyup.png
但實際放大後發現,兩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支持~

https://button.like.co/jm-ysys18


本文參考

https://www.wpgdadatong.com/tw/blog/detail?BID=B0956


尚未有邦友留言

立即登入留言