[STM32] 15-ADC_Conversion
Analog to Digital Conversion , ADC 類比 — 數位轉換可將類比物理量轉換成數位訊號進行處理。STM32 提供 12 位元解析度的 ADC 轉換,用來作為電壓監測或物理性感測器訊號取樣非常方便。本文章介紹 STM32 的 ADC 功能,以 STM32CubeIDE 開發環境搭配 Hardware Abstraction Layer, HAL 函式庫進行實作。
文章內容
- STM32 的 ADC 介紹
- 轉換模式
- 實作
- 成果展示
工具與材料
- STM32CubeIDE
- Blue Pill ( STM32F103C8T6 ) 開發板
- ST-LINK v2
- 10 KΩ 可變電阻 * 1
- 麵包板與單芯線
STM32 的 ADC 介紹
Analog — Digital Conversion, ADC 是一項成熟的技術,隨著科技進步在解析度與轉換時間上有著顯著改善。STM32 內建了 ADC 功能其特性如下:
特性:
- 12 位元解析度,轉換結果為 0 ~ 4095 。
- 單次、連續、掃描與間斷轉換模式。
- 16 位元資料暫存器儲存轉換結果,可設定左、右對齊格式。
- 看門狗監測輸入電壓是否超過上、下限。
- 由 PCLK2 提供時脈源,不可超過 14 MHz。
- 可藉由外部觸發轉換。
- ADC 電源 2.4 v ~ 3.6 v 。
- ADC 待測電壓範圍 Vref — < Vin < Vref + 。
STM 32 的 ADC 系統方塊圖
STM32F103C8T6 ADC 通道對應的腳位
通道分組
STM32 提供了多個通道進行 ADC 轉換,應用上可分成兩組搭配使用。
- Regular Channels 常規通道 : 一般轉換工作皆使用常規通道,用於循序性的轉換程序。
- Injected Channels 注入通道 : 相當於 「 插隊 」,在常規通道轉換期間插隊進行注入通道的轉換,完成注入通道轉換後再回到常規通道進行轉換,由於是用來插隊的功能因此要有觸發源來啟動注入轉換。
轉換時間
ADC 轉換時間 = 取樣時間 + 12.5 個週期
其中取樣時間有以下選擇,一般而言取樣時間長越準確。
1.5、7.5、13.5、28.5、41.5、55.5、71.5、239.5 個週期。
範例: 設 ADCCLK = 12 MHz ,取樣時間設為 13.5 個週期,則
ADC 轉換時間為 1 / 12 * ( 13.5 + 12.5 ) = 0.083 u * 26 = 2.17 us
換算結果
ADC 的解析度是 12 位元,2 的 12 次方是 4096 代表會將物理量分成 4096 等分,以 STM32 而言 ADC 的參考電壓如果相同於電源電壓 3.3 v ,那麼 1 等分就是 3.3 / 4096 = 0.806 mv。
轉換後的數值與待測電壓的換算就是 待測電壓 = ( 轉換數值 * 3.3 ) / 4096 。
轉換模式
一、Single Conversion Mode 單次轉換模式
單次轉換模式,可以軟體啟動或外部觸發啟動,ADC 只執行一次轉換在完成後隨即停止。
完成轉換後將結果儲存在 16 位元的 暫存器 ADC_DR 中,並設立 End of Conversion, EOC 旗標。
二、Continous Conversion Mode 連續轉換模式
連續轉換模式,可以軟體啟動或外部觸發啟動 在完成一次轉換後隨即進行下一次轉換並且不間斷,可用在需要連續監控的場合。
三、Scan Mode 掃描模式
掃描模式,可以對一組通道依自訂順序做轉換。掃描模式需啟用 DMA 來傳遞轉換結果。
四、Discontinous Mode 間斷模式
透過觸發來啟動轉換,可以將排定的轉換通道分組進行轉換,每觸發一次便轉換一組。
例如:有數個轉換通道 0、1、2、3、4、7、9、10,以 3 個通道為一組。
- 第一次觸發,轉換通道 0、1、2。
- 第二次觸發,轉換通道 3、4、7。
- 第三次觸發,轉換通道 9、10。並設立轉換完成旗標 EOC。
完成一輪轉換後不會自動下一輪轉換,等到第四次觸發產生才從 0、1、2 通道開始新一輪轉換。
綜合上述,應用上可以搭配不同轉換模式達到需求。
- 單通道單次轉換 ( 單次轉換模式 )。
- 單通道連續轉換 ( 連續轉換模式 )。
- 多通道單次轉換 ( 掃描模式 + 單次轉換模式 )。
- 多通道連續轉換 ( 掃描模式 + 連續轉換模式 )。
- 間斷轉換。
實作
本次實驗使用可變電阻進行電位調整,可變電阻上的電壓 0 ~ 3.3 v ,而 ADC 參考電源為 3.3 v,因此當我們轉動可變電阻時預期會得到 0 ~ 4095 之間的轉換結果。電路設計上使用一個可變電阻連接至 STM32 的 PA0取樣通道,並利用 HAL 函式庫來完成程式撰寫。
一、開啟 STM32CubeIDE 開發環境,建立一個新的專案。
二、選擇微處理器型號,輸入F103C8 可以快速找到,選擇該型號後按下 「Next」鍵。
三、輸入專案名稱後按下「Finish」鍵。
四、設定 SYS ,這邊的 Debug 選項選擇 「Serial Wire」。
五、RCC 時脈源,HSE 選擇 「Crystal / Ceramic Resonator」,其中 HSE 是連接開發板上的 8 MHz 震盪器提供系統使用。
六、點開 「Analog」可以看到 ADC1 與 ADC2 ,點選 ADC1 後會出現設定畫面。
PA1 腳位對應 ADC 的 Channel 0,所以選擇 「IN0」。
參數設定如下:
- Mode 使用獨立模式 「Independent Mode」。
- Data Alignment 選擇右對齊 「Right Alignment」。
- Scan Conversion Mode 是否開啟掃描模式,選擇 「Disabled」。
- Continous Conversion Mode 是否開啟連續轉換模式,選擇 「Enabled」。
- Discontinous Conversion Mode 是否開啟間斷模式,選擇 「Disabled」。
- Enable Regular Conversions 是否開啟常規轉換,選擇 「Enable」。
- Number of Conversion 待轉換通道數量,選擇 「1」。
- Rank 轉換通道排序,因為只用一個通道所以只會顯示一個,若啟用多通道那麼就會有多個 Rank 需要設定。Rank 1 的 Channel 選擇 「Channel 0 」。Sampling Time 取樣時間,可依需求選擇,這裡選擇 「7.5 Cycle」。
開啟 ADC 中斷
七、Clock Configuration 設定系統時脈為 72 MHz,ADC 時脈為 12 MHz 。
八、產生程式碼,可以按存檔鍵或是點擊上方 「Project 」=> 「Generate Code 」產生程式碼。
九、產生程式碼後便可開始撰寫程式,首先宣告兩個變數分別用來儲存 ADC 轉換結果以及換算成對應的電壓。在 * USER CODE BEGIN 0 * 區段宣告兩個變數。
uint32_t ADC_Result = 0;float ADC_Voltage = 0;
在 USER CODE BEGIN 2 區段進行 ADC 校正後啟動帶有中斷的 ADC 轉換功能。
HAL_ADCEx_Calibration_Start(&hadc1);HAL_ADC_Start_IT(&hadc1);
因為要利用中斷所以要找到 Call Back 函式,在左邊的 Project Explore 點開路徑,Core => Src => STM32f1xx_it.c 找到 ADC_1_2_IRQHandler(void),滑鼠點兩下即開啟該函式所在位置。
之後將 「HAL_ADC_IRQHandler」以滑鼠選起來後按滑鼠右鍵,選擇 Open Decaration 開啟該函式所在位置,找到 「void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)」即是我們要找的 Call Back 函式。
將其複製後貼到 main.c 主程式下方的 USER CODE BEGIN 4 區段。其中,要將最後的 hadc 改成 hadc1,並寫下程式敘述
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1){ADC_Result = HAL_ADC_GetValue(hadc1); // 取得轉換結果存到變數 ADC_ResultADC_Voltage = (float)ADC_Result * 3.3 / 4096; // 換算成對應電壓}
十、完成程式碼撰寫後進行編譯程序,按下綠色箭頭按鈕。
十一、在 Debugger 項目將 「ST-LINK S/N 」打勾並點擊右方 「SCAN」按鈕。
此時會顯示 ST-Link v2 編號,沒問題後按下 「OK 」按鈕即開始編譯並上傳程式到開發板。
十二、點擊甲蟲符號進行 Debug 程序,我們要利用 Live Expression 觀察解果。
在畫面右手邊找到 Live Expression 後新增兩個變數,ADC_Result , ADC_Voltage。
完成後,點擊綠色小箭頭 ( Resume ) 即可開始監看變數內容。由於是連續模式所以會一直顯示轉換結果,當轉動可變電阻時可以觀察到數值跟著改變。
電路圖
成果展示
這次實驗使用一個可變電阻以連續轉換模式監看電壓。轉換完成後啟動中斷並在中斷回調函式中取得結果並進行換算,此種方式並不甚好,因為 ADC 轉換很快,以此設定而言,ADC 時脈為 12 MHz ,取樣時間設定 7.5 個週期,依公式可以得到轉換時間為 1 / 12 * ( 7.5 + 12.5 ) = 0.083 u * 20 = 1.67 us 如此頻繁進行中斷會造成負擔。然而對於單通道這樣簡單的應用,採用輪詢或中斷是最簡單的方式。
總結
STM32 提供多通道 ADC 取樣,在轉換時間與解析度皆能應付一般所需。本文章總結如下。
- 12 位元解析度,將待測電壓分為 4096 等分。
- 取樣頻率由 PCLK2 提供,最高可達 14 MHz 。
- 16 位元儲存轉換結果,可選擇左、右對齊格式。
- 單次、連續、掃描與間斷轉換。
- 阻斷 ( Block ) 、中斷 ( Interrupt ) 與 DMA ( Direct Memory Access ) 等方式傳遞轉換結果。
相關文章
- [STM32] 00-Install STM32CubeIDE [連結]
- [STM32] 01-ST-LINK [連結]
- [STM32] 02-STM32F103C8T6 [連結]
- [STM32] 03-GPIO-Output [連結]
- [STM32] 04-GPIO-Input [連結]
- [STM32] 05-Ext-Interrupt [連結]
- [STM32] 06-Timer-Basic [連結]
- [STM32] 07-Timer-Interrupt [連結]
- [STM32] 08-Timer-Output_Compare [連結]
- [STM32] 09-Timer-PWM [連結]
- [STM32] 10-Timer-Input_Capture [連結]
- [STM32] 11-RTC-Second-Interrupt [連結]
- [STM32] 12-RTC-Alarm_Interrupt [連結]
- [STM32] 13-Independent_Watch_Dog [連結]
- [STM32] 14-Windows_Watch_Dog [連結]
- [STM32] 15-ADC_Conversion [連結]
- [STM32] 16-ADC_Conversion_Temperature_Sensor [連結]
- [STM32] 17-ADC_Convversion_DMA [連結]
- [STM32] 18-SPI [連結]
- [STM32] 19-UART [連結]
- [STM32] 20-I2C [連結]