一、内部温度传感器简介
温度传感器生成一个随温度变化的电压。内部 ADC 将传感器电压转化为一个数字量。温度传感器的测量范围为 –20 °C 到 110 °C。温度传感器适用于监测芯片内部温度的变化,该温度值会随着微控制器时钟频率或 IO 负载的变化而变化。一般来讲,芯片内部温度会高于外部温度。
温度传感器的输出值需要使用转换公式转换成实际的温度值(℃)。转换公式如下:
其中 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, // Select RC_FAST as the source clockTEMPERATURE_SENSOR_CLK_SRC_DEFAULT = SOC_MOD_CLK_TEMP_SENSOR, // Select RC_FAST as the default choice
} soc_periph_temperature_sensor_clk_src_t;
2.2、使能温度传感器
我们可以使用 temperature_sensor_enable()
函数 使能温度传感器,它的函数原型如下:
/*** @brief 使能内部温度传感器* * @param tsens 内部温度传感器句柄* @return esp_err_t ESP_OK表示使能成功,其它表示使能失败*/
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_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));}
}