ST意法半导体
直播中

李慧

8年用户 971经验值
私信 关注
[问答]

STM32H743IIT6同时配置ADC3通道中的温度及内部参考电压,扫描单次转换,如何读出这二个数据?

单个读出倒是整明白了,但二个同时配置并启用扫描方式,应该怎才能读出实时转换的数据呢?
谢谢。

回帖(1)

淡淡的爱

2025-6-19 18:03:46

要正确配置STM32H743IIT6的ADC3同时读取内部温度传感器和参考电压(VREFINT),并使用单次扫描模式,需遵循以下步骤。核心思路是利用DMA传输多通道数据,并正确配置采样顺序:


1. 启用内部传感器和参考电压


ADC_Common中启用温度传感器和VREFINT:


   HAL_ADCEx_EnableVREFINT();      // 启用VREFINT内部参考电压
   HAL_ADCEx_EnableTemperatureSensor(); // 启用温度传感器

2. 配置ADC3通道


选择ADC3通道:



  • 温度传感器通道:ADC_CHANNEL_TEMPSENSOR (通道18)

  • VREFINT通道:ADC_CHANNEL_VREFINT (通道0)


3. 配置扫描模式


设置ADC3为:



  • 扫描模式:启用多通道扫描

  • 单次转换模式:每次启动只执行一轮扫描

  • DMA传输:自动将多通道结果搬运到内存数组


4. 完整代码示例


#include "stm32h7xx_hal.h"

ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;

// 用于存储转换结果的数组(索引0: VREFINT, 索引1: 温度)
uint32_t adc_results[2];

void ADC3_Init(void) {
  // 1. 启用内部传感器
  HAL_ADCEx_EnableVREFINT();
  HAL_ADCEx_EnableTemperatureSensor();

  // 2. 配置DMA(确保DMA流对应ADC3)
  hdma_adc3.Instance = DMA1_Stream0; // 使用正确的DMA流(查数据手册)
  hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
  hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
  hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  hdma_adc3.Init.Mode = DMA_NORMAL; // 单次模式
  HAL_DMA_Init(&hdma_adc3);
  __HAL_LINKDMA(&hadc3, DMA_Handle, hdma_adc3);

  // 3. 配置ADC3
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B; // 16位模式
  hadc3.Init.ScanConvMode = ENABLE;          // 启用扫描
  hadc3.Init.ContinuousConvMode = DISABLE;   // 单次转换
  hadc3.Init.DMAContinuousRequests = DISABLE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
  HAL_ADC_Init(&hadc3);

  // 4. 配置通道(顺序决定结果数组索引)
  ADC_ChannelConfTypeDef sConfig = {0};

  // 通道0 (VREFINT)
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  sConfig.Rank = ADC_REGULAR_RANK_1;          // 第一个转换
  sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES; // 长采样时间确保精度
  HAL_ADC_ConfigChannel(&hadc3, &sConfig);

  // 通道18 (温度传感器)
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_2;         // 第二个转换
  HAL_ADC_ConfigChannel(&hadc3, &sConfig);

  // 5. 校准ADC
  HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
}

// 启动ADC转换并读取数据
void Read_Temp_Vref(void) {
  HAL_ADC_Start_DMA(&hadc3, adc_results, 2); // 启动DMA传输到adc_results
  while (HAL_ADC_PollForConversion(&hadc3, 100) != HAL_OK); // 等待转换完成

  // 此时adc_results数组已更新:
  //   uint32_t vrefint_value = adc_results[0]; // VREFINT原始值
  //   uint32_t temp_value = adc_results[1];    // 温度传感器原始值
}

5. 数据处理



  • VREFINT:可用于计算实际电压(参考手册提供典型值VREFINT_CAL

  • 温度计算
    float calc_temperature(uint32_t adc_temp) {
    float vsense = adc_temp * 3.3f / 65535; // 假设参考电压=3.3V
    return (vsense - 0.76f) / 0.0025f + 25; // 公式见手册
    }


关键点说明



  1. DMA必要性和作用:扫描模式中,ADC会自动切换通道,但结果寄存器ADC_DR会被覆盖。DMA确保在每次转换后立刻将数据保存到指定数组。

  2. 采样顺序:通过Rank参数设置通道转换顺序(ADC_REGULAR_RANK_1优先)。

  3. 采样时间:内部传感器需要较长的采样时间(推荐≥810周期)。

  4. 数据对齐:16位分辨率需对齐到uint32_t数组(实际有效位为16位)。

  5. 单次模式:每次读取需调用HAL_ADC_Start_DMA()重新启动。



注意:温度传感器的精度受芯片工作电压影响,建议通过VREFINT进行校准(详见STM32H7参考手册)。



按照此流程,即可在扫描模式下同步获取两个内部通道的数据。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分