本文介紹了STM32 ADC使用類比看門狗(AWD)的基本方法。從AWD的初步使用開始,涵蓋了實驗流程的規劃、電路設計以及AWD設定。最後,通過實際實驗驗證了當電壓超出預定範圍時,AWD會觸發中斷函數以應對當前情況。
Outline
STM32 ADC Analog Watchdog (AWD) 介紹
以下以reference manual來說明
如果ADC轉換的模擬電壓低於低閾值(LTR)或高於高閾值(HTR),則模擬看門狗(AWD)狀態位將被設置。這些閾值在ADC_HTR和ADC_LTR 16位寄存器的12個最低有效位中進行編程。可以通過在ADC_CR1寄存器中使用AWDIE位來啟用中斷。
閾值設定與在ADC_CR2寄存器中由ALIGN位選擇的對齊方式無關。比較動作在對齊之前進行。
模擬看門狗可以通過配置ADC_CR1寄存器,在一個或多個通道上啟用。
AWDIE:模擬看門狗中斷啟用 此位由軟件設定和清除,用於啟用/禁用模擬看門狗中斷。
0:模擬看門狗中斷禁用
1:模擬看門狗中斷啟用
以上是對AWD的筆記。
STM32 ADC AWD 實驗規劃
針對AWD實驗,規劃了實驗流程如下:
首先啟用ADC的Continuous Conversion Mode,硬體能夠不斷地觸發ADC的轉換,接下來設置LED長亮狀態,透過AWD不斷的檢查當前ADC內的ADC_DR是否超出設置的HTR或LTR,如果超出LED閃爍5次,反之持續LED維持長亮。
GPIO設定當AWD中斷發生以閃爍LED警告。
下面是設置ADC Configuration的參數,需要注意到Continuous Conversion Mode需要被Enable的,High/Low Threshold也需要設置,
分別為3473(約2.8 Volt = 3479 x 0.000806 volt)和1241(約1.0 Volt = 1241 x 0.000806 volt),最後WatchDog Interrupt也需要Enable。
ADC1的global interrupts中斷是需要Enable的,如下:
在本次實驗的實驗電路如下,高電位3.3 Volt、低電位0 Volt,下方可變電阻約為48k歐姆,上方進行調整可變電阻(0 ~ 250k歐姆)來觀察此次AWD實驗。當超過或低於Analog watchdog guarded ares時,LED會進行閃爍。
以上完成之後,接下來看看實驗結果。
STM32 ADC AWD 實驗結果
Global變數宣告
- u32_ADC_DR:用來暫存ADC_DR的數值
- IN0_Voltage:用來暫存ADC_DR轉換成電壓的值
1 2 3 4 |
/* USER CODE BEGIN PV */ uint32_t u32_ADC_DR; float IN0_Voltage; //單位: volt /* USER CODE END PV */ |
ADC1初始化
- ADC_Enable:啟用ADCON
- HAL_ADCEx_Calibration_Start:校正指定ADC
- HAL_ADC_Start:開始測量轉換類比訊號。
1 2 3 4 5 6 |
/* USER CODE BEGIN ADC1_Init 2 */ ADC_Enable(&hadc1); HAL_ADCEx_Calibration_Start(&hadc1); Usr_AsmDelay_us(2); HAL_ADC_Start(&hadc1); /* USER CODE END ADC1_Init 2 */ |
AWD中斷函數(需實現HAL_ADC_LevelOutOfWindowCallback)
Analog watchdog callback in non blocking mode.
當發生Level Out Of Window的情況,將會執行以下程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/* USER CODE BEGIN 4 */ void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* NOTE : This function should not be modified. When the callback is needed, function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file. */ if(hadc->Instance == hadc1.Instance) { //User To Do... int alartCnt = 0; do { HAL_GPIO_TogglePin(AlartLed_GPIO_Port, AlartLed_Pin); Usr_AsmDelay_ms(100); }while(alartCnt++ < 10); HAL_GPIO_WritePin(AlartLed_GPIO_Port, AlartLed_Pin, GPIO_PIN_RESET); } } /* USER CODE END 4 */ |
Main函數
在while loop中,不斷地將ADC_DR資料放置u32_ADC_DR中,並換算實際電壓數值放置IN0_Voltage。
1 2 3 4 5 6 7 8 9 10 11 |
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ u32_ADC_DR = hadc1.Instance->DR; IN0_Voltage = u32_ADC_DR * 0.000806f; } /* USER CODE END 3 */ |
下方是AWD實驗影片,當上方電阻值變大,ADC量測值將會小於1 Volt,影片中右手方的Led會開始閃爍,直到上方電阻值變小。
下方是ADC量測值1659,在Analog watchdog guarded ares範圍內(1241 ~ 3473),並未觸發中斷導致Led閃爍。
下方是ADC量測值1218,在Analog watchdog guarded ares範圍內(1241 ~ 3473),並觸發中斷導致Led閃爍。
結論
在這篇學習了AWD的使用方式,並透過基礎的電路實驗證明了AWD的作用,以及程式碼的撰寫方式,提供各位學習STM32 ADC AWD的使用者們。