要正确配置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. 数据处理
关键点说明
- DMA必要性和作用:扫描模式中,ADC会自动切换通道,但结果寄存器
ADC_DR会被覆盖。DMA确保在每次转换后立刻将数据保存到指定数组。
- 采样顺序:通过
Rank参数设置通道转换顺序(ADC_REGULAR_RANK_1优先)。
- 采样时间:内部传感器需要较长的采样时间(推荐≥810周期)。
- 数据对齐:16位分辨率需对齐到
uint32_t数组(实际有效位为16位)。
- 单次模式:每次读取需调用
HAL_ADC_Start_DMA()重新启动。
注意:温度传感器的精度受芯片工作电压影响,建议通过VREFINT进行校准(详见STM32H7参考手册)。
按照此流程,即可在扫描模式下同步获取两个内部通道的数据。