STM32學習心得二十四:內部溫度傳感器原理及實驗

記錄一下,方便以後翻閱~
主要內容:
1) STM32內部溫度傳感器概述;
2) 相關實驗代碼解讀。
實驗功能:系統啓動後,實時將內部溫度傳感器的值傳至串口助手上。
官方資料:《STM32中文參考手冊V10》第11章——溫度傳感器
1. 內部溫度傳感器框圖
在這裏插入圖片描述
2. STM32內部溫度傳感器概述
2.1 STM32有一個內部的溫度傳感器,可以用來測量CPU及周圍的溫度(TA);
2.2 該溫度傳感器在內部和ADCx_IN16輸入通道相連接,此通道把傳感器輸出的電壓轉換成數字值;
2.3 溫度傳感器模擬輸入推薦採樣時間是17.1μs(最快);
2.4 STM32的內部溫度傳感器支持的溫度範圍爲:-40~125度。精度比較差,爲±1.5℃左右。
備註:內部溫度傳感器更適合於檢測溫度的變化,而不是測量絕對溫度。如果需要測量絕度溫度,應該使用一個外部溫度傳感器。
3. STM32F10x系列芯片ADC通道和引腳對應關係
在這裏插入圖片描述
4. 內部溫度傳感器使用注意事項:
4.1 要使用STM32的內部溫度傳感器,必須先激活ADC的內部通道,通過ADC_CR2寄存器的TSVREFE位(bit23)設置。設置該位爲1則啓用內部溫度傳感器。
在這裏插入圖片描述
4.2 STM32的內部溫度傳感器固定的連接在ADC的通道16上,所以,在設置好ADC之後只要讀取通道16的值,就是溫度傳感器返回來的電壓值。根據該值,可計算出當前溫度,公式如下:
T=[(V25-Vsense)/Avg_Slope]+25
上式中:
V25——Vsense在25度時的數值(典型值爲:1.43);
Avg_Slope——溫度與Vsense曲線的平均斜率(單位爲mv/℃或uv/℃)(典型值爲4.3Mv/℃);
利用以上公式,可以計算出當前溫度傳感器的溫度。
在這裏插入圖片描述
5. 開啓內部溫度傳感器步驟:
5.1 選擇ADC_IN16輸入通道;
5.2 設置採樣時間大於17.1us;
5.3 設置ADC_CR2的TSVREFE位,打開內部溫度傳感器;
5.4 設置ADON位啓動轉換;
5.5 讀取ADC結果;
5.6 計算。
6. 相關實驗代碼解讀
6.1 tsensor.h頭文件代碼解讀

#ifndef __TSENSOR_H
#define __TSENSOR_H 
#include "stm32f10x.h"  
short Get_Temprate(void);                
void Adc_Init(void);                     
u16  Get_Adc(u8 ch);                      
u16  Get_Adc_Average(u8 ch,u8 times);        
#endif 

6.2 tsensor.c文件代碼解讀

#include "tsensor.h"
#include "delay.h"
#include "sys.h" 
//編寫Adc_Init初始化函數//
void Adc_Init(void)  
{
 ADC_InitTypeDef ADC_InitStructure; 
 //使能GPIOA,ADC1通道時鐘//
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );   
 //設置ADC時鐘,對RCC_CFGR時鐘配置寄存器的位[14~15] ADCPRE操作//
 RCC_ADCCLKConfig(RCC_PCLK2_Div6);   
 ADC_DeInit(ADC1);  //將外設 ADC1 的全部寄存器重設爲缺省值//
 //ADC_InitStructure參數設置//
 //ADC_CR1寄存器,位[19:16]:DUALMODE雙模式選擇,ADC_Mode_Independent=0x00000000,獨立模式//
 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
 //ADC_CR1寄存器,位8:SCAN掃描模式,0關閉掃描模式//
 ADC_InitStructure.ADC_ScanConvMode = DISABLE; 
 //ADC_CR2寄存器,位1:CONT連續轉換,0單次轉換模式//
 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 
 //ADC_CR2寄存器,位[19:17]:EXTSEL選擇啓動規則通道組轉換的外部事件,ADC_ExternalTrigConv_None=0x000E0000,SWSTART軟件控制// 
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 
 //ADC_CR2寄存器,位11:ALIGN數據對齊,ADC_DataAlign_Right=0x00000000,右對齊//
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 
 //ADC_SQR1寄存器,位[23:20]:L規則通道序列長度,1指1個轉換,即位[23:20]設爲0000//
 ADC_InitStructure.ADC_NbrOfChannel = 1; 
 ADC_Init(ADC1, &ADC_InitStructure); 
 //ADC_CR2寄存器,位23:TSVREFE溫度傳感器和Vrefint使能,啓動溫度傳感器//
 ADC_TempSensorVrefintCmd(ENABLE); 
 ADC_Cmd(ADC1, ENABLE);                          //使能指定的ADC1//
 //下面四個函數用於校準//
 ADC_ResetCalibration(ADC1);                     //重置指定的ADC1的復位寄存器//
 while(ADC_GetResetCalibrationStatus(ADC1));     //獲取ADC1重置校準寄存器的狀態,設置狀態則等待//
 ADC_StartCalibration(ADC1);                     //開啓AD校準//
 while(ADC_GetCalibrationStatus(ADC1));          //獲取指定ADC1的校準程序,設置狀態則等待//
}
//編寫Get_Adc函數,獲取溫度傳感器的原始值(二進制轉十進制的值)//
u16 Get_Adc(u8 ch)   
 {
  //設置指定ADC的規則組通道,四個入口參數//
 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );         
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);            //使能指定的ADC1的軟件轉換啓動功能//
 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));    //等待轉換結束,EOC=1時,轉換完成,則While停止//
 return ADC_GetConversionValue(ADC1);               //返回最近一次ADC1規則組的轉換結果//
 }
//取times次,然後平均,取溫度傳感器採集的原始值(十進制值)//
u16 Get_Adc_Average(u8 ch,u8 times)
{
 u32 temp_val=0;
 u8 t;
 for(t=0;t<times;t++)
 {
  temp_val+=Get_Adc(ch);
  delay_ms(5);
 }
 return temp_val/times;
}     
short Get_Temprate(void)                     //獲取內部溫度傳感器溫度值//
{
 u32 adcx;
 double temperate;
 adcx=Get_Adc_Average(ADC_Channel_16,20);    //讀取通道16,20次取平均//
 temperate=(float)adcx*(3.3/4096);           //先轉成電壓值//
 temperate=(1.43-temperate)/0.0043+25;       //再轉換爲溫度值//   
 return temperate;
}

6.3 main.c文件代碼解讀

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"  
#include "tsensor.h"
 int main(void)
 {  
 float temp;   
 delay_init();          //延時函數初始化   
 uart_init(115200);     //串口初始化爲115200
 LED_Init();            //初始化與LED連接的硬件接口
 Adc_Init();            //ADC初始化        
 while(1)
 {
  temp=Get_Temprate();  //得到溫度值// 
  printf("芯片溫度:%.1f\n",temp); 
  LED0=!LED0;
  delay_ms(500); 
 } 
}

7. 實驗效果
在這裏插入圖片描述
舊知識點
1)複習如何新建工程模板,可參考STM32學習心得二:新建工程模板
2)複習基於庫函數的初始化函數的一般格式,可參考STM32學習心得三:GPIO實驗-基於庫函數
3)複習寄存器地址,可參考STM32學習心得四:GPIO實驗-基於寄存器
4)複習位操作,可參考STM32學習心得五:GPIO實驗-基於位操作
5)複習寄存器地址名稱映射,可參考STM32學習心得六:相關C語言學習及寄存器地址名稱映射解讀
6)複習時鐘系統框圖,可參考STM32學習心得七:STM32時鐘系統框圖解讀及相關函數
7)複習延遲函數,可參考STM32學習心得九:Systick滴答定時器和延時函數解讀
8)複習ST-LINK仿真器的參數配置,可參考STM32學習心得十:在Keil MDK軟件中配置ST-LINK仿真器
9)複習ST-LINK調試方法,可參考STM32學習心得十一:ST-LINK調試原理+軟硬件仿真調試方法
10)複習如何對GPIO進行復用,可參考STM32學習心得十二:端口複用和重映射
11)複習串口通信相關知識,可參考STM32學習心得十四:串口通信相關知識及配置方法
12)複習ADC原理及一般配置步驟,可參考STM32學習心得二十三:ADC轉換原理及模數轉換實驗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章