超级版主
 
- 积分
- 5300
- 金钱
- 5300
- 注册时间
- 2019-5-8
- 在线时间
- 1357 小时
|
|
第三十章 内部温度传感器实验
1)实验平台:正点原子DNESP32P4开发板
2)章节摘自【正点原子】ESP32-P4开发指南— V1.0
3)购买链接:https://detail.tmall.com/item.htm?id=873309579825
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32P4.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子DNESP32S3开发板技术交流群:132780729
本章将介绍ESP32-P4的内部温度传感器并使用它来读取温度值,然后在LCD模块上显示出来。
本章分为如下几个小节:
30.1 内部温度传感器介绍
30.2 硬件设计
30.3 程序设计
30.4 下载验证
30.1 内部温度传感器介绍
温度传感器生成一个随温度变化的电压,内部ADC将传感器电压转化为一个数字量。温度传感器的测量范围为–40℃到125℃。温度传感器适用于监测芯片内部温度的变化,该温度值会随着微控制器时钟频率或IO负载的变化而变化。一般来讲,芯片内部温度会高于外部温度。ESP32-P4温度传感器相关内容,请看技术手册48章节。
温度传感器的输出值需要使用转换公式转换成实际的温度值(℃)。转换公式如下:
T(℃) = 0.4386 * VALUE –27.88 * offset – 20.52 其中VALUE即温度传感器的输出值,offset由温度偏移决定。温度传感器在不同的实际使用环境(测量温度范围)下,温度偏移不同,见下表所示。
表30.1.1 温度传感器的温度偏移
30.2 硬件设计
30.2.1 例程功能
通过对应接口函数读取ESP32-P4内部温度传感器的温度值,显示在LCD屏上。LED0闪烁用于提示程序正在运行。
30.2.2 硬件资源
1)LED灯
LED 0 - IO51
2)RGBLCD / MIPILCD(引脚太多,不罗列出来)
30.2.3 原理图
内部温度传感器属于ESP32-P4的片上资源,因此没有对应的连接原理图。
30.3 程序设计
30.3.1 内部温度传感器的IDF驱动
使用内部温度传感器相关功能函数,必须先导入以下头文件:
- #include "driver/temperature_sensor.h"
复制代码 接下来,作者将介绍一些常用的函数,这些函数的描述及其作用如下:
1,创建温度传感器函数temperature_sensor_install
该函数用于创建温度传感器模块,其函数原型如下:
- esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_config, temperature_sensor_handle_t *ret_tsens);
复制代码 函数形参:
表30.3.1.1 temperature_sensor_install函数形参描述
函数返回值:
ESP_OK表示创建成功。
tsens_config为指向内部温度传感器配置结构体指针。介绍temperature_sensor_config_t结构体中各个成员,如下代码所示:
- typedef struct {
- int range_min; /* 所测量温度范围的最小值 */
- int range_max; /* 所测量温度范围的最大值 */
- temperature_sensor_clk_src_t clk_src; /* 内部温度传感器时钟源 */
- } temperature_sensor_config_t;
复制代码 评估测量范围,进而对range_min和range_max成员设置,而clk_src时钟源成员直接选择TEMPERATURE_SENSOR_CLK_SRC_DEFAULT即可。在内部温度传感器驱动中,提供有默认配置宏TEMPERATURE_SENSOR_CONFIG_DEFAULT(min, max),可以直接使用,取代对成员赋值。
ret_tsens为指向内部温度传感器句柄结构体指针,temperature_sensor_handle_t不需要了解。
2,启用温度传感器函数temperature_sensor_enable
该函数用于启用温度传感器,其函数原型如下:
- esp_err_t temperature_sensor_enable(temperature_sensor_handle_t tsens);
复制代码 函数形参:
表30.3.1.2 temperature_sensor_enable函数形参描述
函数返回值:
ESP_OK表示启用温度传感器成功。
ESP_ERR_INVALID_STATE表示温度传感器已经被启用。
3,获取测量的温度值函数temperature_sensor_get_celsius
该函数用于获取当前测量的温度值,其函数原型如下:
- esp_err_t temperature_sensor_get_celsius( temperature_sensor_handle_t tsens,
- float *out_celsius);
复制代码 函数形参:
表30.3.1.2 temperature_sensor_get_celsius函数形参描述
函数返回值:
ESP_OK表示温度数据测量成功。
ESP_ERR_INVALID_ARG表示错误参数。
ESP_ERR_INVALID_STATE表示温度传感器未启用。
ESP_FAIL表示传感器数据解析为环境温度失败(大多属于超出温度范围)。
30.3.2 程序流程图
图30.3.2.1 内部温度实验程序流程图
30.3.3 程序解析
在21_tsens例程中,作者在21_tsens\components\BSP路径下新建了1个文件夹SENSOR,并且需要更改CMakeLists.txt内容,以便在其他文件上调用。
1. SENSOR驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。SENSOR驱动源码包括两个文件:sensor.c和sensor.h。
sensor.h主要用于声明sensor_inter_init等函数,以便在其他文件中调用,具体内容不再赘述。
下面我们再解析sensor.c的程序,首先介绍内部温度传感器初始化函数sensor_inter_init,代码如下:
- <font size="3">/**</font>
- <font size="3"> * @brief 初始化内部温度传感器</font>
- <font size="3"> * [url=home.php?mod=space&uid=271674]@param[/url] 无</font>
- <font size="3"> * @retval ESP_OK:初始化成功</font>
- <font size="3"> */</font>
- <font size="3">esp_err_t sensor_inter_init(void)</font>
- <font size="3">{</font>
- <font size="3">temperature_sensor_config_t temp_sensor_config = </font>
- <font size="3">TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); /* 设置测试温度范围10~50 */</font>
- <font size="3">/* 创建温度传感器模块 */</font>
- <font size="3">ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor_config, </font>
- <font size="3">&temp_handle)); </font>
- <font size="3"> ESP_ERROR_CHECK(temperature_sensor_enable(temp_handle)); /* 启动温度传感器 */</font>
- <font size="3"> return ESP_OK;</font>
- <font size="3">}</font>
复制代码 在sensor_inter_init函数中,首先对temp_sensor_config结构体变量的成员进行赋值,采用的是TEMPATURE_SENSOR_CONFIG_DEFAULT宏函数,然后调用temperature_sensor_install配置测量范围。后续便可以调用temperature_sensor_enable函数启用温度传感器。
接下来,介绍一下温度数据获取函数sensor_inter_get_temperature,代码如下:
- <font size="3">/**</font>
- <font size="3"> * @brief 获取内部温度传感器温度值</font>
- <font size="3"> * @param 无</font>
- <font size="3"> * @retval 返回内部温度值</font>
- <font size="3"> */</font>
- <font size="3">float sensor_inter_get_temperature(void)</font>
- <font size="3">{</font>
- <font size="3"> float temperature = 0;</font>
- <font size="3">/* 获取当前测量的温度值 */</font>
- <font size="3"> ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_handle, &temperature)); </font>
- <font size="3"> return temperature;</font>
- <font size="3">}</font>
复制代码 该函数主要通过调用temperature_sensor_get_celsius函数实现的。这里的温度值是浮点类型,最终作为函数的返回值。
2. CMakeLists.txt文件
本例程的功能实现主要依靠SENSOR驱动。要在main函数中,成功调用SENSOR文件中的内容,就得需要修改BSP文件夹下的CMakeLists.txt文件,修改如下:
- <font size="3">set(src_dirs</font>
- <font size="3"> LED</font>
- <font size="3"> LCD</font>
- <font size="3"> SENSOR)</font>
- <font size="3">set(include_dirs</font>
- <font size="3"> LED</font>
- <font size="3"> LCD</font>
- <font size="3"> SENSOR)</font>
- <font size="3">set(requires</font>
- <font size="3"> driver</font>
- <font size="3"> esp_lcd</font>
- <font size="3"> esp_common)</font>
- <font size="3">idf_component_register( SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})</font>
- <font size="3">component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)</font>
复制代码 3. main.c驱动代码
在main.c里面编写如下代码。
- <font size="3">void app_main(void)</font>
- <font size="3">{</font>
- <font size="3"> esp_err_t ret;</font>
- <font size="3"> float tsens_temperature = 0;</font>
- <font size="3"> uint32_t data_tmp = 0;</font>
- <font size="3"> </font>
- <font size="3"> ret = nvs_flash_init(); /* 初始化NVS */</font>
- <font size="3"> if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)</font>
- <font size="3"> {</font>
- <font size="3"> ESP_ERROR_CHECK(nvs_flash_erase());</font>
- <font size="3"> ESP_ERROR_CHECK(nvs_flash_init());</font>
- <font size="3"> }</font>
- <font size="3"> led_init(); /* LED初始化 */</font>
- <font size="3"> lcd_init(); /* LCD屏初始化 */</font>
- <font size="3"> sensor_inter_init(); /* 温度传感器初始化 */</font>
- <font size="3"> lcd_show_string(30, 50, 200, 16, 16, "ESP32-P4", RED);</font>
- <font size="3"> lcd_show_string(30, 70, 200, 16, 16, "Temperature TEST", RED);</font>
- <font size="3"> lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);</font>
- <font size="3"> lcd_show_string(30, 110, 200, 16, 16, "Temperature: 00.00C", BLUE);</font>
- <font size="3"> while (1)</font>
- <font size="3"> {</font>
- <font size="3"> tsens_temperature = sensor_inter_get_temperature(); /* 得到温度值 */</font>
- <font size="3"> if (tsens_temperature < 0)</font>
- <font size="3"> {</font>
- <font size="3"> tsens_temperature = -tsens_temperature;</font>
- <font size="3"> lcd_show_char(126, 110, '-', 16, 0, BLUE); /* 显示负符号 */ </font>
- <font size="3"> }</font>
- <font size="3"> else</font>
- <font size="3"> {</font>
- <font size="3"> lcd_show_char(126, 110, ' ', 16, 0, BLUE); /* 无符号 */</font>
- <font size="3"> }</font>
- <font size="3"> data_tmp = (uint32_t)tsens_temperature; /* 取整数部分 */</font>
- <font size="3"> lcd_show_num(134, 110, data_tmp, 2, 16, BLUE); /* 显示整数部分 */ </font>
- <font size="3"> data_tmp = (tsens_temperature - data_tmp) * 100; /* 取2位小数部分 */</font>
- <font size="3"> lcd_show_xnum(158, 110, data_tmp, 2, 16, 0x80, BLUE); /* 显示小数部分 */</font>
- <font size="3"> </font>
- <font size="3"> LED0_TOGGLE();</font>
- <font size="3"> vTaskDelay(pdMS_TO_TICKS(200));</font>
- <font size="3"> }</font>
- <font size="3">}</font>
复制代码 在app_main函数中,完成外设初始化后,进入到死循环,调用sensor_inter_get_temperature函数获取温度数据。获取到温度数据后,根据温度值判读正负,来显示温度符号,再显示整数和小数部分。LED0闪烁,以提示程序正在运行。
30.4 下载验证
将程序下载到开发板后,可以看到LED0不停闪烁,提示程序已经在运行了。LCD显示的内容如下图30.4.1所示。
图30.4.1 内部温度传感器实验程序运行效果图 |
|