ADC的管脚是直接接的4650电源芯片的输出脚,但是获取的值偏小,1.8V的值只有1.2V,2V的值只有1.5V,这是什么原因?
下面是我的配置:
void ADC1_DMA_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* ---------------- 1. 开启时钟 ---------------- */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* ---------------- 2. GPIO 模拟输入配置 ---------------- */
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;//GPIO_MODE_INPUT;//GPIO_MODE_ANALOG;
// PA0 ~ PA6
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// PB0 ~ PB1
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// PC0 ~ PC5
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
GPIO_PIN_4|GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ---------------- 3. DMA 配置 (对应 DMA1_Channel1) ---------------- */
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; // 外设到内存
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址不递增
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; // 内存地址递增
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; // 16位数据
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; // 16位数据
hdma_adc1.Init.Mode = DMA_CIRCULAR; // 循环模式
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; // 高优先级
HAL_DMA_Init(&hdma_adc1);
// 将 DMA 句柄链接到 ADC 句柄
__HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
/* ---------------- 4. ADC1 模式配置 ---------------- */
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // 开启扫描模式
hadc1.Init.ContinuousConvMode = ENABLE; // 开启连续转换
hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁用间断模式
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
hadc1.Init.NbrOfConversion = ADC_CHANNEL_COUNT; // 转换通道数
HAL_ADC_Init(&hadc1);
/* ---------------- 5. 规则序列与采样时间配置 ---------------- */
// 统一配置为最高 239.5 周期,防止通道切换时的“鬼影电荷”影响
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
// 依次将 15 个通道填入 Rank 1 到 Rank 15
sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_REGULAR_RANK_1; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_2; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = ADC_REGULAR_RANK_3; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = ADC_REGULAR_RANK_4; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = ADC_REGULAR_RANK_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = ADC_REGULAR_RANK_6; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_6; sConfig.Rank = ADC_REGULAR_RANK_7; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_8; sConfig.Rank = ADC_REGULAR_RANK_8; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_9; sConfig.Rank = ADC_REGULAR_RANK_9; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_10; sConfig.Rank = ADC_REGULAR_RANK_10; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = ADC_REGULAR_RANK_11; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_12; sConfig.Rank = ADC_REGULAR_RANK_12; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_13; sConfig.Rank = ADC_REGULAR_RANK_13; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_14; sConfig.Rank = ADC_REGULAR_RANK_14; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_15; sConfig.Rank = ADC_REGULAR_RANK_15; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// --- 内部温度通道 (Rank 16, 对应 CH16) ---
// 配置宏会自动开启 ADC_CR2_TSVREFE (温度传感器和VREFINT使能位)
// sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
// sConfig.Rank = ADC_REGULAR_RANK_16;
// HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// --- 内部基准电压通道 (Rank 17, 对应 CH17) ---
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_16;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
ADC1->CR2 |= ADC_CR2_TSVREFE;
HAL_Delay(2);
/* ---------------- 6. ADC 校准与启动 ---------------- */
HAL_ADCEx_Calibration_Start(&hadc1);
// 启动 ADC 的 DMA 传输
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_raw_buffer, ADC_CHANNEL_COUNT);
}
void ADC1_GetVoltages(void)
{
if( (DMA1->ISR & 0×00000002) != RESET ){
for(uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++)
{
voltage_array[i] = ((float)adc_raw_buffer[i] / 4095.0f) * 3.3;
}
voltage_array[15] = (4095*1.20f)/adc_raw_buffer[15];
}
}