基本配置步骤
-
使能时钟

- 使能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工具可自动生成初始化代码。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/285683.html

