打印
[STM32G4]

STM32G431KBU3芯片内部温度读取的实例代码

[复制链接]
6108|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dffzh|  楼主 | 2025-5-22 17:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dffzh 于 2025-6-4 17:24 编辑

#申请原创#
@21小跑堂

我们有时候会利用MCU芯片内部的温度传感器来读取MCU温度,并用此温度数据来做一些应用功能,比如参数随温度动态调整,监控MCU芯片温度或者线性调整温度偏移等功能。这篇文章作者就带大家看一下如何读取STM32的STM32G431KBU3芯片的内部温度数据。通过整个读取过程的操作,以后大家遇到其他芯片,也可以按这个步骤进行尝试。
1、先看手册
我们先来看下芯片数据手册,找到与内部温度传感器相关的章节介绍,主要如下:
温度数据一般来源于模拟信号,那肯定是用ADC模块,所以我们先确认绑定了ADC外设的哪个通道,这个时候就需要打开数据手册或者用户手册来查看:


从用户手册可以看出,内部温度传感器是绑定了ADC1的16通道和ADC5的4通道。
再来看看对温度传感器的说明,读取流程和计算方法:



如果公式里面有一些常量参数值,也要看下如何读取出来:
2、再写代码
知道怎么读取芯片的温度传感器数据和计算方法后,接下来就可以编写代码调试了。
代码主要涉及ADC初始化配置和温度读取两个方面。
其中读取芯片内部温度传感器的ADC通道对应的宏是:
ADC初始化配置接口为MX_ADC_Init,代码如下:
void MX_ADC_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.GainCompensation = 0;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */
}
读取出厂校准点参数的代码如下:
uint8_t TS_CAL1_TEMP = 30;
uint8_t TS_CAL2_TEMP = 130;
uint16_t TS_CAL1 = 0;
uint16_t TS_CAL2 = 0;
//存储校准参数的地址
#define TS_CAL1_ADDR   0x1FFF75A8
#define TS_CAL2_ADDR   0x1FFF75CA

//从地址里读取所存的数据
uint8_t read_from_flash(uint32_t addr)
{
        return *(uint8_t*)addr;
}
void read_g4_temp_cal(void)
{
        uint8_t ts_cal_value_1 = 0;
        uint8_t ts_cal_value_2 = 0;

        HAL_FLASH_Unlock();

        ts_cal_value_1 = read_from_flash(TS_CAL1_ADDR);
        ts_cal_value_2 = read_from_flash(TS_CAL1_ADDR+1);
        TS_CAL1 = ts_cal_value_1 | (ts_cal_value_2 << 8);

        ts_cal_value_1 = read_from_flash(TS_CAL2_ADDR);
        ts_cal_value_2 = read_from_flash(TS_CAL2_ADDR+1);
        TS_CAL2 = ts_cal_value_1 | (ts_cal_value_2 << 8);

        HAL_FLASH_Lock();
}

读取并转换温度的代码如下:
void read_g4_temperature(void)
{
        uint16_t adc_value = 0;

        //1.read adc value
        HAL_ADC_Start(&hadc1);
        HAL_ADC_PollForConversion(&hadc1, 100);
        while(!HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC));
        adc_value = HAL_ADC_GetValue(&hadc1);
        AD_Value = adc_value *3.3/3;
        //2.calculate actual temperature
        g4_temp = ((TS_CAL2_TEMP - TS_CAL1_TEMP)*(AD_Value - TS_CAL1)/(TS_CAL2 - TS_CAL1)) + 30;
        //3. test
        //*ADC_PartStruct[0].Objects.objChannelValue = g4_temp;
        sCh1Value = g4_temp;
        //HAL_Delay(500);
}

3、最后测试验证
代码写好并且编译通过后,就是上板验证看看能不能成功读取温度。在Keil里使用jlink仿真器进行调试,全速运行后,看指示温度(单位为摄氏度)的全局变量的值从开始的21慢慢上升到27:
又升到了29:
从以上的仿真验证结果可以看出,读取MCU芯片内部温度传感器的代码和数据基本上是准确的。
不过这里没有考虑到精度问题,如果是对温度精度要求不高的场景,可以使用MCU内部温度作为数据源,如果是对温度精度要求比较高的场景,比如要保留几位小数点等,最好是先确认下你所用的MCU的内部温度传感器的精度,但是一般情况下建议直接使用外置的温度传感器,比如PT100或者热电偶之类的。

以上通过读取STM32G431KBU3芯片的内部温度数据,给大家提供了一种读取MCU芯片内部温度的基本方法,可以作为温度测试的一种参考。

83434682ee9923a587.png (15.81 KB )

83434682ee9923a587.png

使用特权

评论回复
评论
dffzh 2025-6-4 17:22 回复TA
@21小跑堂 :本地文档查看是有超过800字的(算上代码),我又增加了文字描述,请原创审核哦! 
21小跑堂 2025-6-4 16:47 回复TA
感谢大佬分享本文未满800字不予审核 
沙发
gaonaiweng| | 2025-5-31 18:14 | 只看该作者
重点看温度计算公式和校准参数

使用特权

评论回复
板凳
dffzh|  楼主 | 2025-6-4 09:22 | 只看该作者
gaonaiweng 发表于 2025-5-31 18:14
重点看温度计算公式和校准参数

是的呢。

使用特权

评论回复
地板
EchoInEons| | 2025-6-14 18:44 | 只看该作者
看下初始化校准,是否需要标定还是每次出场的时候标定一次即可?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

758

帖子

9

粉丝