STM32 ADC如何配置?详细步骤与参数设置指南
- 虚拟主机
- 2026-02-07
- 3302
基本配置步骤
-
使能时钟
- 使能GPIO时钟(对应ADC通道引脚)
- 使能ADC时钟
-
配置GPIO
将引脚设置为模拟模式
-
配置ADC参数
- 分辨率(12/10/8/6位)
- 扫描模式(单通道/多通道)
- 连续转换模式
- 触发方式(软件/外部触发)
- 数据对齐(右对齐/左对齐)
-
配置ADC通道
- 选择通道序号
- 设置采样时间
-
校准ADC

- 执行复位校准
- 执行校准
-
启动转换
- 软件触发转换
- 等待转换完成
- 读取转换结果
单通道轮询模式示例代码(ADC1, 通道0, PA0)
#include "stm32f4xx.h" void ADC1_Init(void) { // 1. 使能时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 2. 配置GPIO GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; // 模拟模式 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // 3. 配置ADC参数 ADC_InitTypeDef ADC_InitStruct; ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; // 12位分辨率 ADC_InitStruct.ADC_ScanConvMode = DISABLE; // 单通道模式 ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // 连续转换 ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // 软件触发 ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐 ADC_InitStruct.ADC_NbrOfConversion = 1; // 1个转换通道 ADC_Init(ADC1, &ADC_InitStruct); // 4. 配置ADC通道 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_84Cycles); // PA0对应通道0 // 5. 校准ADC ADC_Cmd(ADC1, ENABLE); // 使能ADC ADC_ResetCalibration(ADC1); // 复位校准 while(ADC_GetResetCalibrationStatus(ADC1));// 等待复位完成 ADC_StartCalibration(ADC1); // 开始校准 while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成 // 6. 启动转换 ADC_SoftwareStartConv(ADC1); // 软件触发转换 } uint16_t Read_ADC(void) { while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换完成 return ADC_GetConversionValue(ADC1); // 返回转换结果 } int main(void) { ADC1_Init(); while(1) { uint16_t adc_value = Read_ADC(); // 使用adc_value(0~4095对应0~3.3V) // 添加延时或处理逻辑 } }
多通道扫描模式(使用DMA)
关键修改点:
// 启用扫描模式和DMA ADC_InitStruct.ADC_ScanConvMode = ENABLE; // 多通道扫描 ADC_InitStruct.ADC_NbrOfConversion = 3; // 3个通道 // 配置DMA RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); DMA_InitTypeDef DMA_InitStruct; DMA_InitStruct.DMA_Channel = DMA_Channel_0; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)adc_buffer; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStruct.DMA_BufferSize = 3; // 3个通道 DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 循环模式 DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_Init(DMA2_Stream0, &DMA_InitStruct); DMA_Cmd(DMA2_Stream0, ENABLE); // 启用ADC的DMA ADC_DMACmd(ADC1, ENABLE);
关键注意事项
-
采样时间计算:

- 总转换时间 = 采样时间 + 12个周期(12位分辨率)
- 例:ADC_SampleTime_84Cycles + 12 = 96周期 @ ADC时钟=21MHz → 转换时间 ≈ 4.57μs
-
电压计算:
float voltage = (adc_value * 3.3f) / 4095.0f; // VREF=3.3V -
参考电压:
- 确保VREF+引脚连接稳定参考电压(通常使用3.3V)
- 避免超过VDDA电压(0~3.3V输入)
-
校准要求:

- 每次上电后需校准一次
- 温度变化大时建议重新校准
-
中断使用:
- 可启用EOC(转换完成)中断替代轮询
- 配置NVIC并实现中断服务函数
常见问题解决
-
读数不稳定:
- 增加采样时间(如使用ADC_SampleTime_480Cycles)
- 添加RC滤波电路(10kΩ + 100nF)
- 避免高频噪声(远离数字信号线)
-
ADC无法启动:
- 检查时钟使能(APB2时钟和GPIO时钟)
- 验证GPIO配置为模拟模式
- 确保校准流程完整执行
-
多通道数据错位:
- 检查DMA内存地址递增配置
- 确认通道配置顺序与DMA缓存匹配
不同STM32系列(F1/F3/F4/H7)配置存在差异,请参考对应《参考手册》的ADC章节,使用CubeMX工具可自动生成初始化代码。