STM32内部温度传感器使用方法详解

STM32内部温度传感器使用方法详解

前言

STM32内部集成了一个片上温度传感器,可以用来测量MCU及周围的温度。测量范围:-40~125,精度±1.5℃。虽然精度不高,但在某些应用场景下是够了的,相比于外部接入传感器,使用内部温度传感器既可以节省成本,又可以简化电路。

1 温度传感器简介

1.1 工作原理

STM32内部温度传感器在芯片内部与ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值,继而换算成温度值。因此,我们只需设置一下内部ADC,并激活其内部通道就可以了。

温度换算公式如下:

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

注:

1、V25:Vsense在25度时的数值(典型值为:1.43)。

2、Avg_Slope:温度与Vsense曲线的平均斜率(单位为 mv/℃或 uv/℃)(典型值为4.3mv/℃)。

3、Vsense:温度传感器的当前输出电压(温度传感器模拟输入推荐最快采样时间是17.1μs)。

温度传感器特性如下:

1.2 软件配置步骤

1、配置ADC参数。

2、使能内部温度传感器。

3、读取ADC数值并转换成温度值。

1.3 注意事项

1、温度传感器输出电压随温度线性变化,由于生产过程的变化,温度变化曲线的偏移在不同芯片上会有不同(最多相差45°C)。

2、内部温度传感器更适合于检测温度的变化,而不是测量绝对的温度,如果需要测量精确的温度,应该使用一个外置的温度传感器。

3、硬件设计上注意VREF+和VREF-的接入电压(如果该MCU封装有VREF引脚的话,一般64pin及以下的没有)。

2 程序编写

根据上面的原理介绍,使用ADC1的通道16作为采集输入信号,采集到ADC电压值以后根据温度转换公式转换成温度数据。

参考测试代码:

c 复制代码
#include "delay.h"
#include "sys.h"
#include "usart.h"     

// 初始化配置ADC参数(以规则通道为例)
void T_Adc_Init(void)  
{
    ADC_InitTypeDef ADC_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE);      // 使能ADC1通道时钟
  
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   // 分频因子6时钟为72M/6=12MHz
	
    ADC_DeInit(ADC1);  // 将外设ADC1的全部寄存器重设为缺省值
	
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                   // ADC工作模式:ADC1和ADC2工作在独立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;                        // 模数转换工作在单通道模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                  // 模数转换工作在单次转换模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 转换由软件而不是外部触发启动
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;               // ADC数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;                              // 顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);    // 根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

	ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);    // ADC1规则通道转换,采样时间为239.5周期 
 
    ADC_Cmd(ADC1, ENABLE);    // 使能指定的ADC1
	ADC_TempSensorVrefintCmd(ENABLE);  // 开启内部温度传感器
	
    ADC_ResetCalibration(ADC1);     // 重置指定的ADC1的复位寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));    // 获取ADC1重置校准寄存器的状态,设置状态则等待

    ADC_StartCalibration(ADC1);     // ADC1校准
    while(ADC_GetCalibrationStatus(ADC1));        // 获取指定ADC1的校准程序,设置状态则等待

	// ADC_SoftwareStartConvCmd(ADC1,ENABLE); // 软件触发开始
}

// 获取ADC值
uint16_t T_Get_Adc(uint8_t ch)   
{
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);    // ADC1规则通道转换,采样时间为239.5周期                      
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);         // 使能指定的ADC1的软件转换启动功能
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));  // 等待转换结束
    return ADC_GetConversionValue(ADC1);            // 返回最近一次ADC1规则组的转换结果
}

// 获取通道ch的转换值(取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;
}        

// 获取内部温度传感器温度值
// 返回值:温度值(扩大了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;    // 转换为温度值,转换公式:T(℃)= ((V25 - Vsense) / Avg_Slope) + 25
    result = (temperate *= 100);                  // 扩大100倍.
    return result;
}

int main(void)
{     
    int temp; 
	SystemInit();
    delay_init();            // 延时函数初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);       // 串口初始化为115200
    T_Adc_Init();            // ADC初始化              
    while(1)
    {
        temp = Get_Temprate();  // 读取温度值 
        if(temp > 0)
        {// 温度为正数
            printf("temp: %d.%02dC", temp/100, temp%100);
        }
        else
        {// 温度为负数
            printf("temp: %d.%02dC", temp/100, -temp%100);
        }
        delay_ms(500);    
    } 
}

示例代码测试结果:

结束语

上面的测试例子只是给大家做一个参考,实际上需要根据项目的具体需求去补充细节,比如温度的采样方式和采样频率,本文只是用最简单的单次采样,实际上可以使用DMA进行连续采样,跟普通ADC使用是一样的,这里就不再多说了,大家根据自己的实际情况调整即可。

好了,关于STM32如何使用内部温度传感器就介绍到这里,如果你们还有什么问题,欢迎评论区留言。

如果这篇文章能够帮到你,就...懂的。

相关推荐
CODECOLLECT1 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen2 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠4 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_4 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技7 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计7 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦8 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报8 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业8 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能8 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微