[STM32]16-ADC_Conversion_Internal Temperature Sensor

Morgan Ting
閱益如美
Published in
10 min readJun 26, 2022
Photo by Daniela Paola Alchapar on Unsplash

STM32 內建一個溫度感測器可用以監控晶片溫度變化。本文章將介紹 STM32 的內建溫度感測器,使用開發環境為 STM32CubeIDE 並搭配 Hardware Abstracion Layer, HAL 函式庫。

文章內容

  1. STM32 Internal Temperature Sensor
  2. 實作
  3. 成果展示

工具與材料

  1. STM32CubeIDE
  2. Blue Pill ( STM32F103C8T6 ) 開發板
  3. ST-LINK v2

STM32 Internal Temperature Sensor

溫度感測是常見的物理量量測,溫度是電子元件殺手之一若運作環境溫差大或長期處於高溫皆會導致系統異常甚至元件損壞。STM32 晶片內部也內建了一個溫度感測器,要注意的是該感測器不能取代一般感測器做環境溫度監控以及裝置溫度監控,只做內部溫度感測使用且得到的溫度感測值不可作為絕對參考值。很饒舌,且看以下說明。

STM32 內部溫度感測器放在 Analog to Digital Conversion, ADC 模組裡面,按手冊說明是位於 ADC 第 16 個通道,所以是利用 ADC 轉換得到電壓再套公式去換算,其操作步驟如下:

  • 選擇ADC1_IN16 通道。
  • 取樣時間大於 17.1 us 。
  • 設定 ADC_CR2 暫存器的 TSVREFE 位元,啟動溫度感測器。
  • 設定 ADON 啟動轉換。
  • 讀取轉換結果 VSENSE 。
  • 溫度 ( oC ) = { ( V25 — VSENSE ) / AVG_Slope } + 25 。

系統方塊圖

reference : datasheet

從系統方塊圖看起來操作內部溫度感測器很單純,而且 HAL 函式庫也都把暫存器設定包裝成 APIs ,更加方便。

我們所關心的是最後要如何得到轉換溫度,公式裡的 V25 ,Vsense ,AVG_Slope 又是什麼。

  • V25 ,在溫度 25 度 C 時得到的轉換電壓。
  • Vsense ,我們操作溫度感測器得到的轉換電壓。
  • AVG_Slope ,平均斜率 [ mv / oC ]

手冊上給出以上參數

reference : datasheet

因此,我們要做的就是取得 ADC 轉換結果並換算成對應電壓,最後再套公式便能得到感測溫度。

實作

本次實作以ADC轉換模組中的溫度感測器進行內部溫度量測。其中,溫度感測器位於模組一的第 16 通道,以阻斷式 ( Block ) 方式來操作量測程序並以 Live Expression 觀察量測結果。

一、開啟 STM32CubeIDE 開發環境,建立一個新的專案。

start new project

二、選擇微處理器型號,輸入F103C8 可以快速找到,選擇該型號後按下 「Next」鍵。

target select

三、輸入專案名稱後按下「Finish」鍵。

project name

四、設定 SYS ,這邊的 Debug 選項選擇 「Serial Wire」。

五、RCC 時脈源,HSE 選擇 「Crystal / Ceramic Resonator」,其中 HSE 是連接開發板上的 8 MHz 震盪器提供系統使用。

RCC

六、點開 「Analog」可以看到 ADC1 與 ADC2 ,點選 ADC1 後會出現設定畫面。

這一次要使用溫度感測器,所以選擇 「Temperature Sensor Channel 」。

ADC configuration

參數設定如下:

  • Mode 使用獨立模式 「Independent Mode」。
  • Data Alignment 選擇右對齊 「Right Alignment」。
  • Scan Conversion Mode 是否開啟掃描模式,選擇 「Disabled」。
  • Continous Conversion Mode 是否開啟連續轉換模式,選擇 「Disabled」。
  • Discontinous Conversion Mode 是否開啟間斷模式,選擇 「Disabled」。
  • Enable Regular Conversions 是否開啟常規轉換,選擇 「Enable」。
  • Number of Conversion 待轉換通道數量,選擇 「1」。
  • Rank 轉換通道排序,因為只用一個通道所以只會顯示一個,若啟用多通道那麼就會有多個 Rank 需要設定。Rank 1 的 Channel 選擇 「 Channel Temperature Sensor 」。Sampling Time 取樣時間需大於 17.1 us ,這裡選擇 「239.5 Cycle」。

轉換時間 1/12 MHz * ( 239.5 + 12.5 ) = 0.08 us * 252 = 20.16 us 有大於 17.1 us 。

parameter setting

七、Clock Configuration 設定系統時脈為 72 MHz,ADC 時脈為 12 MHz 。

clock configuration

八、project manager 原則上不需要設定,看一下是否有異即可。

九、產生程式碼,可以按存檔鍵或是點擊上方 「Project 」=> 「Generate Code 」產生程式碼。

Generate Code

十、產生程式碼後便可開始撰寫程式,宣告三個全域變數分別用來儲存 ADC 轉換結果與換算成對應的電壓以及換算溫度。在 / * USER CODE BEGIN 0 * / 區段宣告三個變數。

uint32_t ADC_Result = 0;float ADC_Voltage = 0;float ADC_Temperature = 0;

在 / * USER CODE BEGIN 2 * / 區段寫一段校正指令,此指令也可以不寫。

HAL_ADCEx_Calibration_Start(&hadc1);

在循環迴圈 while 中寫以下程式

HAL_ADC_Start(&hadc1); // 開始轉換HAL_ADC_PollForConversion(&hadc1, 1); // 等待轉換完成,超時時間設 1 毫秒ADC_result = HAL_ADC_GetValue(&hadc1); // 取得轉換結果HAL_ADC_Stop(&hadc1); // 停止轉換ADC_Voltage = (float) ADC_result * 3.3 / 4096; // 換算成對應電壓ADC_Temperature = (1.43 — ADC_Voltage) / 0.0043 + 25; // 換算成溫度HAL_Delay(500); // 延遲 500 毫秒
code

十一、完成程式碼撰寫後進行編譯程序,按下綠色箭頭按鈕。

run

十二、在 Debugger 項目將 「ST-LINK S/N 」打勾並點擊右方 「SCAN」按鈕。

此時會顯示 ST-Link v2 編號,沒問題後按下 「OK 」按鈕即開始編譯並上傳程式到開發板。

debugger

十三、點擊甲蟲符號進行 Debug 程序,我們要利用 Live Expression 觀察解果。

在畫面右手邊找到 Live Expression 後新增變數,ADC_Result , ADC_Voltage,ADC_Temperature。

Live Expression

完成後,點擊綠色小箭頭 ( Resume ) 即可開始監看變數內容。完成一次轉換後會稍停 500 毫秒,之後再進行下一輪轉換,所以每隔 0.5 秒會看到新的數值。

result

總結

本次 STM32 內部溫度感測器實驗利用內建於 ADC 轉換模組的溫度感測器量測內部溫度,其中也有一些問題,例如:轉換溫度與室溫有些許差距,開發板置於麵包板上周邊無其他元件,晶片溫度應該不至於與室溫差距太大。其二,每一次轉換 ( 斷電重啟 ) 得到的數值差異甚大,有時會出現負值,依公式 V25 = 1.43 v 減去轉換電壓,若轉換電壓大於 V25 便會出現負值,又因為 AVG_Slope = 4.3 mv / C 斜率是正的所以量測曲線是往上走,那麼量測值大於 V25 也很正常,因為 V25 是室溫 25 度 C 時得到的電壓。總而言之,如手冊所述量測結果不是絕對數值,應該專注在 「溫度變化 」。

本文章總結如下:

  • STM32 內部感測器位於 ADC 1模組通道 16 。
  • 取樣時間應大於 17.1 us 。
  • 轉換溫度不是確切溫度,應著重在溫度變化。
  • 轉換公式 溫度 ( oC ) = { ( V25 - VSENSE ) / AVG_Slope } + 25 。
  • 其中,V25 = 1.43 v ,AVG_Slope = 4.3 mv / C

參考資料

  1. STM32F103 手冊 [ 連結 ]
  2. STM32F1 HAL and Low-layer drivers [ 連結 ]
  3. STM32F103 電氣特性 [ 連結 ]

感謝讀者

若文章有幫助到您可以拍手給我鼓勵,免費支持我。

相關文章

  • [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 [連結]

--

--

Morgan Ting
閱益如美

用好奇心探索世界。喜愛學習樂於分享。