OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2821|回复: 0

《STM32F407 探索者开发指南》第三十二章 内部温度传感器实验

[复制链接]

1140

主题

1152

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4895
金钱
4895
注册时间
2019-5-8
在线时间
1248 小时
发表于 2023-8-7 14:16:56 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2023-8-7 14:24 编辑

第三十二章 内部温度传感器实验

1)实验平台:正点原子探索者STM32F407开发板

2) 章节摘自【正点原子】STM32F407开发指南 V1.1


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/stm32/zdyz_stm32f407_explorerV3.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)STM32技术交流QQ群:151941872

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

本章,我们将介绍STM32F407的内部温度传感器并使用它来读取温度值,然后在LCD模块上显示出来。
本章分为如下几个小节:
32.1 内部温度传感器简介
32.2 硬件设计
32.3 程序设计
32.4 下载验证

32.1 内部温度传感器简介
STM32F407有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA)。对于STM32F407系列来说,该温度传感器在内部和ADC1_INP16(STM32F40xx/F41xx系列)或ADC_IN18(STM32F42xx/F43xx)输入通道相连接,此通道把传感器输出的电压转换成数字值。STM32F4的内部温度传感器支持的温度范围为:-40~125度。精度为±1.5℃左右。

STM32F407内部温度传感器的使用很简单,只要设置一下内部ADC,并激活其内部温度传感器通道就差不多了。关于ADC的设置,我们在上一章已经进行了详细的介绍,这里就不再多说。接下来我们介绍一下和温度传感器设置相关的两个地方。

第一个地方,我们要使用STM32F407的内部温度传感器,必须先激活ADC的内部通道,这里通过ADC_CCR的VSENSEEN位(bit23)设置。设置该位为1则启用内部温度传感器。
第二个地方,STM32F407ZGT6的内部温度传感器固定的连接在ADC1的通道16上,所以,我们在设置好ADC1之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:
QQ截图20230807142125.png
式子中:
V25 = Vsense 在25度时的数值(典型值为:1.43)
Avg_Slope = 温度与Vsense曲线的平均斜率(单位:mv/℃或uv/℃)(典型值:4.3mv/℃)。

利用以上公式,我们就可以方便的计算出当前温度传感器的温度了。

现在,我们就可以总结一下STM32内部温度传感器使用的步骤了,如下:

1)设置ADC,并开启ADC_CR2的VSENSEEN位。
关于如何设置ADC,请参考上一章对单通道ADC采集实验的设置,都是大同小异。然后,我们需要设置ADC_CR2寄存器的VSENSEEN位为1,开启内部温度传感器。

2)读取ADC通道16AD值,计算结果。
在设置完之后,我们就可以读取温度传感器的电压值了,得到该值就可以用上面的公式计算温度值了。

32.2 硬件设计
1. 例程功能
通过ADC1的通道16读取STM32F407内部温度传感器的电压值,并将其转换为温度值,显示在TFTLCD屏上。LED0闪烁用于提示程序正在运行。

2. 硬件资源
1)LED灯
    LED0 – PF9
2)串口1(PA9/PA10连接在板载USB转串口芯片CH340上面)
3)正点原子2.8/3.5/4.3/7寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
4)ADC1 通道16
5)内部温度传感器

3. 原理图
ADC和内部温度传感器都属于STM32F407内部资源,实际上我们只需要软件设置就可以正常工作,我们需要用到TFTLCD模块显示结果。

32.3 程序设计
32.3.1 ADC的HAL库驱动
本实验用到的ADC的HAL库API函数前面都介绍过,具体调用情况请看程序解析部分。下面介绍读取内部温度传感器ADC值的配置步骤。

读取内部温度传感器ADC值配置步骤
1)开启ADC时钟
通过__HAL_RCC_ADC1_CLK_ENABLE函数开启ADC1的时钟。

2)设置ADC1,开启内部温度传感器
调用HAL_ADC_Init函数来设置ADC1时钟分频系数、分辨率、模式、扫描方式、对齐方式等信息。
注意:该函数会调用:HAL_ADC_MspInit回调函数来完成对ADC底层的初始化,包括:ADC1时钟使能、ADC1时钟源的选择等。

3)配置ADC通道并启动AD转换器
调用HAL_ADC_ConfigChannel()函数配置ADC1通道16,根据需求设置通道、序列、采样时间和校准配置单端输入模式或差分输入模式等。然后通过HAL_ADC_Start函数启动AD转换器。

4)读取ADC值,计算温度
这里选择查询方式读取,在读取ADC值之前需要调用HAL_ADC_PollForConversion等待上一次转换结束。然后就可以通过HAL_ADC_GetValue来读取ADC值。最后根据上面介绍的公式计算出温度传感器的温度值。

32.3.2 程序流程图
QQ截图20230807142146.png
图32.3.2.1 内部温度传感器实验程序流程图

32.3.3 程序解析
1. adc驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。ADC驱动源码包括两个文件:adc.c和adc.h。

adc.h头文件只有一个宏定义和一些函数的声明,该宏定义如下:
  1. #define ADC_TEMPSENSOR_CHX             ADC_CHANNEL_TEMPSENSOR
复制代码
ADC_CHANNEL_TEMPSENSOR就是ADC1通道16连接内部温度传感器的通道16宏定义。我们在定义为ADC_TEMPSENSOR_CHX,可以让大家更容易理解这个宏定义的含义。

下面我们直接介绍adc.c的程序,首先是ADC初始化函数,其定义如下:
  1. /**
  2. *@brief       ADC 内部温度传感器 初始化函数
  3. *  @note      本函数还是使用adc_init对ADC进行大部分配置,有差异的地方再单独配置
  4. *             注意: STM32F4内部温度传感器只连接在ADC1的通道16上, 其他ADC无法进行转换.
  5. *
  6. *@param       无
  7. *@retval      无
  8. */
  9. voidadc_temperature_init(void)
  10. {
  11.    adc_init();               /* 先初始化ADC */
  12.     ADC->CCR |= 1 << 23;    /* 使能内部温度传感器 */
  13. }
复制代码
该函数调用adc_init函数配置了ADC的基础功能参数,我们对内部温度传感器的初始化步骤与普通ADC类似,为了不重复编写代码,我们用位操作函数开启内部温度传感器,把ADC_CCR的VSENSEEN位置1,即ADC->CCR |= 1 << 23;这样子就可以完成对内部温度传感器通道的初始化工作。adc_init的实现代码,可以回顾以下ADC章节内容。

下面是获得ADC转换后的结果函数,其定义如下:
  1. /**
  2. *@brief       获取内部温度传感器温度值
  3. *@param       无
  4. *@retval      温度值(扩大了100倍,单位:℃.)
  5. */
  6. shortadc_get_temperature(void)
  7. {
  8.     uint32_t adcx;
  9.     short result;
  10.     double temperature;
  11.    adcx =adc_get_result_average(ADC_TEMPSENSOR_CHX, 10);
  12.                                                      /* 读取内部温度传感器通道,10次取平均 */
  13.    temperature = (float)adcx*(3.3/4096);              /* 获取电压值 */
  14.    temperature = (temperature - 0.76)/0.0025 + 25;  /* 将电压值转换为温度值 */
  15.    result = temperature *= 100;                        /* 扩大100倍. */
  16.     return result;
  17. }
复制代码
该函数先是调用前面ADC实验章节写好的adc_get_result_average函数取获取通道ch的转换值,然后通过温度转换公式,返回温度值。

本实验都是基于ADC实验实现的函数进行调用实现的,所以对于函数的实现比较模糊的,请回顾前面一章,都有详细的讲解。

2. main.c代码
在main.c里面编写如下代码:
  1. int main(void)
  2. {
  3.     short temp;
  4.    HAL_Init();                                  /* 初始化HAL库 */
  5.    sys_stm32_clock_init(336, 8, 2, 7);     /* 设置时钟, 168Mhz */
  6.    delay_init(168);                            /* 延时初始化 */
  7.    usart_init(115200);                        /* 串口初始化为115200 */
  8.    led_init();                                  /* 初始化LED */
  9.    lcd_init();                                  /* 初始化LCD */
  10.    adc_temperature_init();                   /* 初始化ADC内部温度传感器采集 */
  11.    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
  12.    lcd_show_string(30, 70, 200, 16, 16, "TemperatureTEST", RED);
  13.    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  14.    lcd_show_string(30, 120, 200, 16, 16, "TEMPERATE:00.00C", BLUE);
  15.     while (1)
  16.     {
  17.        temp =adc_get_temperature();     /* 得到温度值 */
  18.        if (temp < 0)
  19.        {
  20.            temp = -temp;
  21.            lcd_show_string(30 + 10 * 8, 120, 16, 16, 16, "-", BLUE);/* 显示负号 */
  22.        }
  23.        else
  24.        {
  25.            lcd_show_string(30 + 10 * 8, 120, 16, 16, 16, " ", BLUE); /* 无符号 */
  26.        }
  27. /* 显示整数部分 */
  28.        lcd_show_xnum(30 + 11 * 8, 120, temp / 100, 2, 16, 0, BLUE);
  29. /* 显示小数部分 */
  30.        lcd_show_xnum(30 + 14 * 8, 120, temp % 100, 2, 16, 0X80, BLUE);
  31.        LED0_TOGGLE();  /* LED0闪烁,提示程序运行 */
  32.        delay_ms(250);
  33.     }
  34. }
复制代码
该部分的代码逻辑很简单,先是得到温度值,再根据温度值判断正负值,来显示温度符号,再显示整数和小数部分。

32.4 下载验证
将程序下载到开发板后,可以看到LED0不停的闪烁,提示程序已经在运行了。LCD显示的内容如图32.4.1所示:     
image005.png
图32.4.1 内部温度传感器实验测试图

大家可以看看你的温度值与实际是否相符合(因为芯片会发热,所以一般会比实际温度偏高)?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 08:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表