ITPub博客

首页 > 嵌入式/内核开发 > 嵌入式/内核开发 > 《STM32H562开发指南 V1.0 》第三十章 内部温度传感器实验

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

原创 嵌入式/内核开发 作者:正点原子 时间:2025-12-08 09:18:24 0 删除 编辑

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


       本章,我们将介绍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的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:

       上式中:

       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 程序流程图


图30.3.2.1 内部温度传感器实验程序流程图


       30.3.3 程序解析


       1. adc驱动代码

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

       adc.h头文件只有一个宏定义和一些函数的声明,该宏定义如下:

#define ADC_TEMPSENSOR_CHX             ADC_CHANNEL_TEMPSENSOR

       ADC_CHANNEL_TEMPSENSOR就是ADC1通道16连接内部温度传感器的通道16宏定义。我们在定义为ADC_TEMPSENSOR_CHX,可以让大家更容易理解这个宏定义的含义。

       下面我们介绍一下adc.c文件的代码,因为我们用到ADC1,所以ADC1初始化函数等代码和单通道ADC采集实验的是一模一样的,就不再列出来了,请参考源码。

       这里主要介绍一下获取内部温度传感器温度值函数,函数定义如下:

/**
 * @brief       获取内部温度传感器温度值
 * @param       无
 * @retval      温度值(扩大了100倍,单位:℃.)
 */
short adc_get_temperature(void)
{
    uint32_t adcx;
    short result;
    double temperature;
    float temp = 0;
    uint16_t ts_cal1, ts_cal2;
 
    ts_cal1 = *(volatile uint16_t *)(0x08FFF814);           /* 获取TS_CAL1 */
    ts_cal2 = *(volatile uint16_t *)(0x08FFF818);           /* 获取TS_CAL2 */
    temp = (float)((110.0 - 30.0) / (ts_cal2 - ts_cal1));   /* 获取比例因子 */
/* 读取内部温度传感器通道,10次取平均 */
    adcx = adc_get_result_average(ADC_TEMPSENSOR_CHX, 10); 
 
    temperature = (float)(temp * (adcx - ts_cal1) + 30);    /* 计算温度 */
 
    result = temperature *= 100;                             /* 扩大100倍. */
    return result;
}

       该函数根据ADC1通道16采集温度传感器返回来的电压值代入30.1小节介绍的公式来计算出当前温度值。


       2. main.c代码

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

int main(void)
{
    short temp;
 
    HAL_Init();                                     /* HAL库初始化 */
    sys_stm32_clock_init(250, 4, 2, 2);         /* 系统时钟初始化, 250Mhz */
    delay_init(250);                                /* 延时初始化 */
    usart_init(115200);                            /* 串口初始化 */
    led_init();                                       /* LED初始化 */
    lcd_init();                                       /* LCD初始化 */
    adc_init();                                      /* ADC初始化 */
 
    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "Temperature TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
 
    lcd_show_string(30, 120, 200, 16, 16, "TEMPERATE: 00.00C", BLUE);
 
    while (1)
    {
 
        temp = adc_get_temperature();           /* 得到温度值 */
 
        if (temp < 0)
        {
            temp = -temp;
            lcd_show_string(30 + 10 * 8, 120, 16, 16, 16, "-", BLUE);/* 显示负号 */
        }
        else
        {
            lcd_show_string(30 + 10 * 8, 120, 16, 16, 16, " ", BLUE);/* 无符号 */
        }
/* 显示整数部分 */
        lcd_show_xnum(30 + 11 * 8, 120, temp / 100, 2, 16, 0, BLUE);
/* 显示小数部分 */
        lcd_show_xnum(30 + 14 * 8, 120, temp % 100, 2, 16, 0X80, BLUE); 
 
        LED0_TOGGLE();                 /* LED0闪烁,提示程序运行 */
        delay_ms(250);
    }
}

       该部分的代码逻辑很简单,先是得到温度值,再根据温度值判断正负值,来显示温度符号,再显示整数和小数部分。


        30 .4 下载验证

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


图30.4.1 内部温度传感器实验测试图


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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040860/viewspace-3104609/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-30

  • 博文量
    588
  • 访问量
    764251