13. 内部温度传感器

一、内部温度传感器简介

  温度传感器生成一个随温度变化的电压。内部 ADC 将传感器电压转化为一个数字量。温度传感器的测量范围为 –20 °C 到 110 °C。温度传感器适用于监测芯片内部温度的变化,该温度值会随着微控制器时钟频率或 IO 负载的变化而变化。一般来讲,芯片内部温度会高于外部温度。

  温度传感器的输出值需要使用转换公式转换成实际的温度值(℃)。转换公式如下:

\[T(℃) = 0.4386 * VALUE - 27.88 * offset - 20.52 \]

  其中 VALUE温度传感器的输出值offset温度偏移 决定。温度传感器在不同的实际使用环境(测量温度范围)下,温度偏移不同,见下表所示。

测量范围(℃) 温度偏移(℃)
50 ~ 110 -2
20 ~ 100 -1
-10 ~ 80 0
-15 ~ 50 1
-20 ~ 20 2

二、内部温度传感器常用函数

  ESP IDF 提供了一套 API 来配置温度传感器。要使用此功能,需要导入必要的头文件:

#include "driver/temperature_sensor.h"

2.1、设置测试温度的最大与最小值

  我们可以使用 temperature_sensor_install() 函数 设置测试温度的最大与最小值,它的函数原型如下:

/**
 * @brief 设置测试温度的最大与最小值
 * 
 * @param tsens_config 内部温度传感器配置结构体
 * @param ret_tsens 内部温度传感器句柄
 * @return esp_err_t ESP_OK表示配置成功,其它表示配置失败
 */
esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens);

  形参 tsens_config内部温度传感器配置结构体,它的定义如下:

typedef struct 
{
    int range_min;                              // 温度范围最小值
    int range_max;                              // 温度范围最大值
    temperature_sensor_clk_src_t clk_src;       // 温度传感器时钟源
    struct 
    {
        uint32_t allow_pd;                      // 如果设置,驱动程序将在进入/存在睡眠模式之前/之后备份/恢复温度传感器寄存器。
    } flags;                                    // 温度传感器配置标志

} temperature_sensor_config_t;

  形参 tsens_config 的成员 clk_src温度传感器时钟源,它的取值如下:

typedef enum 
{
    TEMPERATURE_SENSOR_CLK_SRC_RC_FAST = SOC_MOD_CLK_TEMP_SENSOR,
    TEMPERATURE_SENSOR_CLK_SRC_DEFAULT = SOC_MOD_CLK_TEMP_SENSOR,
} soc_periph_temperature_sensor_clk_src_t;

2.2、使能温度传感器

  我们可以使用 temperature_sensor_enable() 函数 使能温度传感器,它的函数原型如下:

/**
 * @brief 使能内部温度传感器
 * 
 * @param tsens 内部温度传感器句柄
 * @return esp_err_t ESP_OK 表示启用温度传感器成功
 *                   ESP_ERR_INVALID_STATE 表示温度传感器已经被启用
 */
esp_err_t temperature_sensor_enable(temperature_sensor_handle_t tsens);

2.3、获取内部温度传感器的数据

  我们可以使用 temperature_sensor_get_celsius() 函数 获取内部温度传感器的数据,它的函数原型如下:

/**
 * @brief 获取内部温度传感器的数据
 * 
 * @param tsens 内部温度传感器句柄
 * @param out_celsius 获取到的传感器数据
 * @return esp_err_t ESP_OK 表示温度数据测量成功
 *                   ESP_ERR_INVALID_ARG 表示错误参数
 *                   ESP_ERR_INVALID_STATE 表示温度传感器未启用
 *                   ESP_FAIL 表示传感器数据解析为环境温度失败(大多属于超出温度范围)
 */
esp_err_t temperature_sensor_get_celsius(temperature_sensor_handle_t tsens, float *out_celsius);

2.4、失能温度传感器

  我们可以使用 temperature_sensor_disable() 函数 失能温度传感器,它的函数原型如下:

/**
 * @brief 失能温度传感器
 * 
 * @param tsens 内部温度传感器句柄
 * @return esp_err_t ESP_OK表示失能成功,其它表示失能失败
 */
esp_err_t temperature_sensor_disable(temperature_sensor_handle_t tsens);

三、实验例程

  这里,我们在【components】文件夹下的【peripheral】文件夹下的【inc】文件夹(用来存放头文件)新建一个 bsp_temperature_sensor.h 文件,在【components】文件夹下的【peripheral】文件夹下的【src】文件夹(用来存放源文件)新建一个 bsp_temperature_sensor.c 文件。

#ifndef __BSP_TEMPERATURE_SENSOR_H__
#define __BSP_TEMPERATURE_SENSOR_H__

#include "driver/temperature_sensor.h"

extern temperature_sensor_handle_t g_temperature_sensor_handle;

void bsp_temperature_sensor_init(temperature_sensor_handle_t *handle, int min, int max);
float bsp_temperature_sensor_get_temperature(temperature_sensor_handle_t handle);

#endif // !__BSP_TEMPERATURE_SENSOR_H__
#include "bsp_temperature_sensor.h"

temperature_sensor_handle_t g_temperature_sensor_handle;

/**
 * @brief 初始化内部温度传感器
 * 
 * @param handle 内部温度传感器句柄
 * @param min 温度范围的最小值
 * @param max 温度范围的最大值
 */
void bsp_temperature_sensor_init(temperature_sensor_handle_t *handle, int min, int max)
{
    temperature_sensor_config_t temperature_sensor_config = {0};

    temperature_sensor_config.clk_src = TEMPERATURE_SENSOR_CLK_SRC_DEFAULT;     // 时钟源
    temperature_sensor_config.range_min = min;                                  // 温度范围的最小值
    temperature_sensor_config.range_max = max;                                  // 温度范围的最大值
    temperature_sensor_install(&temperature_sensor_config, handle);
}

/**
 * @brief 获取内部温度传感器的当前数据
 * 
 * @param handle 内部温度传感器句柄
 * @return float 内部温度传感器的当前数据
 */
float bsp_temperature_sensor_get_temperature(temperature_sensor_handle_t handle)
{
    float temperature = 0;

    temperature_sensor_enable(handle);                                          // 使能温度传感器
    temperature_sensor_get_celsius(handle, &temperature);                       // 获取传输的传感器数据
    temperature_sensor_disable(handle);                                         // 禁用温度传感器,节约功耗

    return temperature;
}

  修改【main】文件夹下的 main.c 文件。

#include <stdio.h>

#include "freertos/FreeRTOS.h"

#include "bsp_temperature_sensor.h"

// app_main()函数是ESP32的入口函数,它是FreRTOS的一个任务,任务优先级是1
// main()函数是C语言入口函数,它会在编译过程中插入到二进制文件中的
void app_main(void)
{
    bsp_temperature_sensor_init(&g_temperature_sensor_handle, 20, 50);
  
    while (1)
    {
        float temperature = bsp_temperature_sensor_get_temperature(g_temperature_sensor_handle);
        printf("temperature: %f\n", temperature);

        // 将一个任务延迟给定的滴答数,IDF中提供pdMS_TO_TICKS可以将指定的ms转换为对应的tick数
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}
posted @ 2025-03-21 22:28  星光映梦  阅读(185)  评论(0)    收藏  举报