OpenEdv-开源电子网

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

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

[复制链接]

1320

主题

1336

帖子

2

精华

超级版主

Rank: 8Rank: 8

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

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

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

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

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

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

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


2.jpg

3.png

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


34.1 内部温度传感器简介
STM32H7R7有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA)。对于STM32H7系列来说,该温度传感器在内部和ADC1_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。STM32H7R7的内部温度传感器支持的温度范围为:-40~125度。精度为±3℃左右。
STM32H7R7内部温度传感器的使用很简单,只要设置一下内部ADC,并激活其内部温度传感器通道就差不多了。关于ADC的设置,我们在上一章已经进行了详细的介绍,这里就不再多说。接下来我们介绍一下和温度传感器设置相关的两个地方。
第一个地方,我们要使用STM32H7R7的内部温度传感器,必须先激活ADC的内部通道,这里通过ADC_CCR的TSEN位(bit23)设置。设置该位为1则启用内部温度传感器。
第二个地方,STM32H7R7L8H6H的内部温度传感器固定的连接在ADC1的通道16上,所以,我们在设置好ADC1之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:
第三十四章 内部温度传感器实验604.png
式子中:
TS_CAL1 是温度传感器在30℃时的校准值,固定保存在芯片内部的:0x08FFF814 ~ 0x08FFF815这两个地址(16位)。
TS_CAL2 是温度传感器在110℃时的校准值,固定保存在芯片内部的:0x08FFF818 ~ 0x08FFF819这两个地址(16位)。
TS_DATA:ADC1通道16读取到的当前温度传感器转换值。
利用以上公式,我们就可以方便的计算出当前温度传感器的温度了。


34.2 硬件设计

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

2. 硬件资源
1)LED灯
       LED0: LED0 – PD14
2)串口1(PB14/PB15连接在板载USB转串口芯片CH340上面)
3)正点原子2.8/3.5/4.3/7/10寸TFTLCD模块(包括MCU屏和RGB屏,都支持)
4)ADC1 通道16
5)内部温度传感器


34.3 程序设计

34.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值。最后根据上面介绍的公式计算出温度传感器的温度值。


34.3.2 程序解析

1. adc驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。ADC驱动源码包括两个文件:adc.c和adc.h。
adc.h头文件只有一些函数的声明,我们直接看adc.c:
ADC_CHANNEL_TEMPSENSOR就是ADC1通道16连接内部温度传感器的宏定义。
下面我们直接看ADC初始化函数,其定义如下:

  1. /**
  2. * @brief   初始化ADC
  3. * [url=home.php?mod=space&uid=271674]@param[/url]   无
  4. * @retval  无
  5. */
  6. void adc_init(void)
  7. {
  8.     /* 初始化ADC */
  9.     g_adc_handle.Instance = ADC1;
  10. g_adc_handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8;      
  11. /* 时钟源和预分频系数 */
  12.     g_adc_handle.Init.Resolution = ADC_RESOLUTION_12B;       /* 分辨率 */
  13.     g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;       /* 数据对齐 */
  14.     g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;       /* 扫描转换模式 */
  15.     g_adc_handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;    /* EOC */
  16.     g_adc_handle.Init.LowPowerAutoWait = DISABLE;            /* 低功耗自动延迟 */
  17.     g_adc_handle.Init.ContinuousConvMode = DISABLE;          /* 连续转换模式 */
  18.     g_adc_handle.Init.NbrOfConversion = 1;          /* 连续转换模式下的转换数量 */
  19.     g_adc_handle.Init.DiscontinuousConvMode = DISABLE;       /* 非连续转换模式 */
  20.     g_adc_handle.Init.NbrOfDiscConversion = 1;      /* 非连续转换模式下的转换数量 */
  21. g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;               
  22. /* 规则组转换外部触发源 */
  23. g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  24. /* 规则组转换外部触发源的有效沿 */
  25. g_adc_handle.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;              
  26. /* 采样模式 */
  27. g_adc_handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;   
  28. /* 管理转换数据 */
  29.     g_adc_handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;    /* 溢出行为 */
  30.     g_adc_handle.Init.OversamplingMode = DISABLE;            /* 过采样模式 */
  31.     HAL_ADC_Init(&g_adc_handle);
  32.    
  33.     /* ADC自动自校准 */
  34.     HAL_ADCEx_Calibration_Start(&g_adc_handle, ADC_SINGLE_ENDED);
  35. }

复制代码
该函数调用adc_init函数配置了ADC的基础功能参数,我们对内部温度传感器的初始化步骤与普通ADC类似。
下面是获得ADC转换后的结果函数,其定义如下:

  1. /**
  2. * @brief   获取内部温度传感器结果
  3. * @param   无
  4. * @retval  温度值(单位:摄氏度)
  5. */
  6. int32_t adc_get_temperature(void)
  7. {
  8. /* HAL库中TEMPSENSOR_CAL1_ADDR和TEMPSENSOR_CAL2_ADDR的定义有误 */
  9. #ifdef TEMPSENSOR_CAL1_ADDR
  10.     #undef TEMPSENSOR_CAL1_ADDR
  11.     #define TEMPSENSOR_CAL1_ADDR ((uint16_t*)(0x08FFF814UL))
  12. #endif
  13. #ifdef TEMPSENSOR_CAL2_ADDR
  14.     #undef TEMPSENSOR_CAL2_ADDR
  15.     #define TEMPSENSOR_CAL2_ADDR ((uint16_t*)(0x08FFF818UL))
  16. #endif
  17.    
  18.     uint32_t result;
  19.    
  20.     result = adc_get_result_average(ADC_CHANNEL_TEMPSENSOR, 10);
  21. return __HAL_ADC_CALC_TEMPERATURE(VREFINT_CAL_VREF, result,
  22. ADC_RESOLUTION_12B);
  23. }
复制代码
该函数先是调用adc_get_result_average函数取获取通道ch的转换值,然后通过温度转换公式,返回温度值。

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

  1. int main(void)
  2. {
  3.     int32_t temperature;
  4.    
  5.     sys_mpu_config();                   /* 配置MPU */
  6.     sys_cache_enable();                 /* 使能Cache */
  7.     HAL_Init();                         /* 初始化HAL库 */
  8.     sys_stm32_clock_init(300, 6, 2);    /* 配置时钟,600MHz */
  9.     delay_init(600);                    /* 初始化延时 */
  10.     usart_init(115200);                 /* 初始化串口 */
  11.     led_init();                         /* 初始化LED */
  12.     hyperram_init();                    /* 初始化HyperRAM */
  13.     lcd_init();                         /* 初始化LCD */
  14.     adc_init();                         /* 初始化ADC */
  15.    
  16.     lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
  17.     lcd_show_string(30, 70, 200, 16, 16, "Temperature TEST", RED);
  18.     lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  19.     lcd_show_string(30, 110, 200, 16, 16, "TEMPERATE: 00C", BLUE);
  20.    
  21.     while (1)
  22.     {
  23.         /* 获取内部温度传感器结果 */
  24.         temperature = adc_get_temperature();
  25.         printf("0x%08X\r\n", temperature);
  26.         
  27.         /* 显示温度 */
  28.         if (temperature < 0)
  29.         {
  30.             temperature = -temperature;
  31.             lcd_show_string(30 + 10 * 8, 110, 16, 16, 16, "-", BLUE);
  32.         }
  33.         else
  34.         {
  35.             lcd_show_string(30 + 10 * 8, 110, 16, 16, 16, " ", BLUE);
  36.         }
  37.         lcd_show_xnum(30 + 11 * 8, 110, temperature, 2, 16, 0, BLUE);
  38.         
  39.         LED0_TOGGLE();
  40.         
  41.         delay_ms(100);
  42.     }
  43. }
复制代码
该部分的代码逻辑很简单,先是得到温度值,再根据温度值判断正负值,来显示温度符号,再显示温度值。

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

第三十四章 内部温度传感器实验5572.png
图34.4.1 内部温度传感器实验测试图

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

使用道具 举报

2

主题

5

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2026-4-28
在线时间
1 小时
发表于 7 小时前 | 显示全部楼层
学习一下,感谢分享
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

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

GMT+8, 2026-4-30 18:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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