OpenEdv-开源电子网

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

《STM32H562开发指南 V1.0 》第三十章 内部温度传感器实验

[复制链接]

1403

主题

1419

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
5984
金钱
5984
注册时间
2019-5-8
在线时间
1688 小时
发表于 1 小时前 | 显示全部楼层 |阅读模式
第三十章 内部温度传感器实验

1)实验平台:正点原子Mini STM32H562开发板

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

3)购买链接: https://detail.tmall.com/item.htm?id=753606659612

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

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

6)正点原子STM32开发板技术交流群:414052738


2.jpg

3.png

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


30.1 内部温度传感器简介
STM32H562有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA)。对于STM32H5系列来说,该温度传感器在内部和ADC1_INP16输入通道相连接,此通道把传感器输出的电压转换成数字值。 STM32H562的内部温度传感器支持的温度范围为:-40~125度。精度为±3℃左右。
STM32H562内部温度传感器的使用很简单,只要设置一下内部ADC,并激活其内部温度传感器通道就差不多了。关于ADC的设置,我们在上一章已经进行了详细的介绍,这里就不再多说。接下来我们介绍一下和温度传感器设置相关的两个地方。
第一个地方,我们要使用STM32H562的内部温度传感器,必须先激活ADC的内部通道,这里通过ADC_ CCR的TSEN位(bit23)设置。设置该位为1,启用内部温度传感器。
第二个地方,STM32H562的内部温度传感器固定的连接在ADC1的通道16上,所以,我们在设置好ADC1之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:


1.png

上式中:
TS_CAL1 是温度传感器在30℃时的校准值,固定保存在芯片内部的:0x08FFF814~ 0x08FFF815这两个地址(16位)。
TS_CAL2 是温度传感器在110℃时的校准值,固定保存在芯片内部的:0x08FFF818~ 0x08FFF819这两个地址(16位)。
TS_DATA:ADC1通道16读取到的当前温度传感器转换值。
利用以上公式,我们就可以方便的计算出当前温度传感器的温度了。


30.2 硬件设计

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

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


30.3 程序设计

30.3.1 ADC的HAL库驱动
本实验用到的ADC的HAL库API函数前面都介绍过,具体调用情况请看程序解析部分。下面介绍读取内部温度传感器ADC值的配置步骤。
读取内部温度传感器ADC值配置步骤
1)开启ADC时钟
通过__HAL_RCC_ADC_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值。最后根据上面介绍的公式计算出温度传感器的温度值。


30.3.2 程序流程图


第三十章 内部温度传感器实验1657.png
图30.3.2.1 内部温度传感器实验程序流程图

30.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文件的代码,因为我们用到ADC1,所以ADC1初始化函数等代码和单通道ADC采集实验的是一模一样的,就不再列出来了,请参考源码。
这里主要介绍一下获取内部温度传感器温度值函数,函数定义如下:

  1. /**
  2. * @brief       获取内部温度传感器温度值
  3. * [url=home.php?mod=space&uid=271674]@param[/url]       无
  4. * @retval      温度值(扩大了100倍,单位:℃.)
  5. */
  6. short adc_get_temperature(void)
  7. {
  8.     uint32_t adcx;
  9.     short result;
  10.     double temperature;
  11.     float temp = 0;
  12.     uint16_t ts_cal1, ts_cal2;

  13.     ts_cal1 = *(volatile uint16_t *)(0x08FFF814);                  /* 获取TS_CAL1 */
  14.     ts_cal2 = *(volatile uint16_t *)(0x08FFF818);                  /* 获取TS_CAL2 */
  15.     temp = (float)((110.0 - 30.0) / (ts_cal2 - ts_cal1));          /* 获取比例因子 */
  16. /* 读取内部温度传感器通道,10次取平均 */
  17.     adcx = adc_get_result_average(ADC_TEMPSENSOR_CHX, 10);

  18.     temperature = (float)(temp * (adcx - ts_cal1) + 30);           /* 计算温度 */

  19.     result = temperature *= 100;                                           /* 扩大100倍. */
  20.     return result;
  21. }
复制代码
该函数根据ADC1通道16采集温度传感器返回来的电压值代入30.1小节介绍的公式来计算出当前温度值。

2. main.c代码
在main.c里面编写如下代码:

  1. int main(void)
  2. {
  3.     short temp;

  4.     HAL_Init();                                            /* HAL库初始化 */
  5.     sys_stm32_clock_init(250, 4, 2, 2);                /* 系统时钟初始化, 250Mhz */
  6.     delay_init(250);                                       /* 延时初始化 */
  7.     usart_init(115200);                                   /* 串口初始化 */
  8.     led_init();                                              /* LED初始化 */
  9.     lcd_init();                                              /* LCD初始化 */
  10.     adc_init();                                             /* ADC初始化 */

  11.     lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
  12.     lcd_show_string(30, 70, 200, 16, 16, "Temperature TEST", 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. }
复制代码
该部分的代码逻辑很简单,先是得到温度值,再根据温度值判断正负值,来显示温度符号,再显示整数和小数部分。

30.4 下载验证
将程序下载到开发板后,可以看到LED0不停的闪烁,提示程序已经在运行了。LCD显示的内容如图30.4.1所示:

第三十章 内部温度传感器实验4338.png
图30.4.1 内部温度传感器实验测试图

大家可以看看你的温度值与实际是否相符合(因为芯片会发热,所以一般会比实际温度偏高)?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

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

GMT+8, 2026-9-7 13:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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