加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

STM32內(nèi)部溫度傳感器使用方法詳解

04/02 07:04
9968
閱讀需 11 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

STM32內(nèi)部集成了一個(gè)片上溫度傳感器,可以用來(lái)測(cè)量MCU及周圍的溫度。測(cè)量范圍:-40~125,精度±1.5℃。雖然精度不高,但在某些應(yīng)用場(chǎng)景下是夠了的,相比于外部接入傳感器,使用內(nèi)部溫度傳感器既可以節(jié)省成本,又可以簡(jiǎn)化電路

1 溫度傳感器簡(jiǎn)介

1.1 工作原理

STM32內(nèi)部溫度傳感器在芯片內(nèi)部與ADCx_IN16輸入通道相連接,此通道把傳感器輸出的電壓轉(zhuǎn)換成數(shù)字值,繼而換算成溫度值。因此,我們只需設(shè)置一下內(nèi)部ADC,并激活其內(nèi)部通道就可以了。

在這里插入圖片描述

溫度換算公式如下:

T(℃)= ((V25 - Vsense) / Avg_Slope) + 25

注:
1、V25:Vsense在25度時(shí)的數(shù)值(典型值為:1.43)。
2、Avg_Slope:溫度與Vsense曲線的平均斜率(單位為 mv/℃或 uv/℃)(典型值為4.3mv/℃)。
3、Vsense:溫度傳感器的當(dāng)前輸出電壓(溫度傳感器模擬輸入推薦最快采樣時(shí)間是17.1μs)。

溫度傳感器特性如下:

在這里插入圖片描述

1.2 軟件配置步驟

1、配置ADC參數(shù)。
2、使能內(nèi)部溫度傳感器。
3、讀取ADC數(shù)值并轉(zhuǎn)換成溫度值。

1.3 注意事項(xiàng)

1、溫度傳感器輸出電壓隨溫度線性變化,由于生產(chǎn)過(guò)程的變化,溫度變化曲線的偏移在不同芯片上會(huì)有不同(最多相差45°C)。
2、內(nèi)部溫度傳感器更適合于檢測(cè)溫度的變化,而不是測(cè)量絕對(duì)的溫度,如果需要測(cè)量精確的溫度,應(yīng)該使用一個(gè)外置的溫度傳感器。
3、硬件設(shè)計(jì)上注意VREF+和VREF-的接入電壓(如果該MCU封裝有VREF引腳的話,一般64pin及以下的沒(méi)有)。

2 程序編寫

根據(jù)上面的原理介紹,使用ADC1的通道16作為采集輸入信號(hào),采集到ADC電壓值以后根據(jù)溫度轉(zhuǎn)換公式轉(zhuǎn)換成溫度數(shù)據(jù)。

參考測(cè)試代碼:

#include "delay.h"
#include "sys.h"
#include "usart.h"     

// 初始化配置ADC參數(shù)(以規(guī)則通道為例)
void T_Adc_Init(void)  
{
    ADC_InitTypeDef ADC_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE);      // 使能ADC1通道時(shí)鐘
  
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   // 分頻因子6時(shí)鐘為72M/6=12MHz
	
    ADC_DeInit(ADC1);  // 將外設(shè)ADC1的全部寄存器重設(shè)為缺省值
	
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                   // ADC工作模式:ADC1和ADC2工作在獨(dú)立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;                        // 模數(shù)轉(zhuǎn)換工作在單通道模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                  // 模數(shù)轉(zhuǎn)換工作在單次轉(zhuǎn)換模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 轉(zhuǎn)換由軟件而不是外部觸發(fā)啟動(dòng)
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;               // ADC數(shù)據(jù)右對(duì)齊
    ADC_InitStructure.ADC_NbrOfChannel = 1;                              // 順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
    ADC_Init(ADC1, &ADC_InitStructure);    // 根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設(shè)ADCx的寄存器

	ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);    // ADC1規(guī)則通道轉(zhuǎn)換,采樣時(shí)間為239.5周期 
 
    ADC_Cmd(ADC1, ENABLE);    // 使能指定的ADC1
	ADC_TempSensorVrefintCmd(ENABLE);  // 開啟內(nèi)部溫度傳感器
	
    ADC_ResetCalibration(ADC1);     // 重置指定的ADC1的復(fù)位寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));    // 獲取ADC1重置校準(zhǔn)寄存器的狀態(tài),設(shè)置狀態(tài)則等待

    ADC_StartCalibration(ADC1);     // ADC1校準(zhǔn)
    while(ADC_GetCalibrationStatus(ADC1));        // 獲取指定ADC1的校準(zhǔn)程序,設(shè)置狀態(tài)則等待

	// ADC_SoftwareStartConvCmd(ADC1,ENABLE); // 軟件觸發(fā)開始
}

// 獲取ADC值
uint16_t T_Get_Adc(uint8_t ch)   
{
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);    // ADC1規(guī)則通道轉(zhuǎn)換,采樣時(shí)間為239.5周期                      
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);         // 使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));  // 等待轉(zhuǎn)換結(jié)束
    return ADC_GetConversionValue(ADC1);            // 返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果
}

// 獲取通道ch的轉(zhuǎn)換值(取times次平均值)
uint16_t T_Get_Adc_Average(uint8_t ch, uint8_t times)
{
    uint32_t temp_val = 0;
    uint8_t t;
    for(t = 0; t < times; t++)
    {
        temp_val += T_Get_Adc(ch);
        delay_ms(5);
    }
    return temp_val / times;
}        

// 獲取內(nèi)部溫度傳感器溫度值
// 返回值:溫度值(擴(kuò)大了100倍,單位:℃)
int Get_Temprate(void)
{
    uint32_t adcx;
    int result;
    double Vsense;
    double temperate;
    adcx = T_Get_Adc_Average(ADC_Channel_16, 20); // 讀取通道16, 20次取平均
    Vsense = (double)adcx * 3.3 / 4096;           // 電壓值 
    temperate = (1.43 - Vsense) / 0.0043 + 25;    // 轉(zhuǎn)換為溫度值,轉(zhuǎn)換公式:T(℃)= ((V25 - Vsense) / Avg_Slope) + 25
    result = (temperate *= 100);                  // 擴(kuò)大100倍.
    return result;
}

int main(void)
{     
    int temp; 
	SystemInit();
    delay_init();            // 延時(shí)函數(shù)初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級(jí)分組為組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
    uart_init(115200);       // 串口初始化為115200
    T_Adc_Init();            // ADC初始化              
    while(1)
    {
        temp = Get_Temprate();  // 讀取溫度值 
        if(temp > 0)
        {// 溫度為正數(shù)
            printf("temp: %d.%02dC", temp/100, temp%100);
        }
        else
        {// 溫度為負(fù)數(shù)
            printf("temp: %d.%02dC", temp/100, -temp%100);
        }
        delay_ms(500);    
    } 
}

示例代碼測(cè)試結(jié)果:

在這里插入圖片描述

結(jié)束語(yǔ)

上面的測(cè)試?yán)又皇墙o大家做一個(gè)參考,實(shí)際上需要根據(jù)項(xiàng)目的具體需求去補(bǔ)充細(xì)節(jié),比如溫度的采樣方式和采樣頻率,本文只是用最簡(jiǎn)單的單次采樣,實(shí)際上可以使用DMA進(jìn)行連續(xù)采樣,跟普通ADC使用是一樣的,這里就不再多說(shuō)了,大家根據(jù)自己的實(shí)際情況調(diào)整即可。

好了,關(guān)于STM32如何使用內(nèi)部溫度傳感器就介紹到這里,如果你們還有什么問(wèn)題,歡迎評(píng)論區(qū)留言。

如果這篇文章能夠幫到你,就…懂的。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
NRF52840-QIAA-R7 1 Nordic Semiconductor Telecom Circuit, 1-Func, PBGA73, AQFN-73
$7.48 查看
CM7V-T1A-LOW-ESR-32.768KHZ-7PF-20-TA-QC 1 Micro Crystal AG Parallel - Fundamental Quartz Crystal,

ECAD模型

下載ECAD模型
$3.02 查看
AT27C512R-45JU-T 1 Microchip Technology Inc OTP ROM, 64KX8, 45ns, CMOS, PQCC32

ECAD模型

下載ECAD模型
$2.23 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜