# STM32F103 PA0到PA4多路ADC采集配置和采集程序
以下是在STM32F103上配置PA0到PA4作为多路ADC输入并进行采集的完整指南。
硬件配置
- STM32F103系列MCU
- PA0-PA4引脚作为ADC输入通道(对应通道0-4)
- 确保模拟输入电压在0-3.3V范围内
使用STM32CubeMX配置
- 打开STM32CubeMX并选择您的STM32F103型号
- 在Pinout & Configuration标签页中:
- 启用ADC1
- 配置PA0-PA4为ADC1_IN0到ADC1_IN4
- 在Configuration标签页的ADC1设置中:
- 设置扫描模式(Scan Conversion Mode)为Enable
- 设置连续转换模式(Continuous Conversion Mode)为Enable
- 设置DMA Continuous Requests为Enable(如果使用DMA)
- 在Rank配置中添加通道0-4,设置采样时间(建议55.5或239.5周期)
不使用CubeMX的寄存器配置
#include "stm32f10x.h"void ADC1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;// 1. 开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);// 2. 配置GPIO为模拟输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 配置ADCADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 扫描模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 5; // 5个通道ADC_Init(ADC1, &ADC_InitStructure);// 4. 配置通道和采样时间ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // PA0ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); // PA1ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5); // PA2ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5); // PA3ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_55Cycles5); // PA4// 5. 使能ADCADC_Cmd(ADC1, ENABLE);// 6. ADC校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
}
多路ADC采集程序
方法1:轮询方式采集
uint16_t ADC_Values[5]; // 存储5个通道的ADC值void ADC_ReadAllChannels(void)
{// 启动转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待转换完成while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));// 读取各通道值for(int i = 0; i < 5; i++){ADC_Values[i] = ADC_GetConversionValue(ADC1);}
}
方法2:使用DMA方式采集(推荐)
#include "stm32f10x_dma.h"uint16_t ADC_Values[5]; // DMA将把ADC值存储到这个数组void ADC1_DMA_Init(void)
{DMA_InitTypeDef DMA_InitStructure;// 1. 开启DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 2. 配置DMADMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Values;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 5;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环模式DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init(DMA1_Channel1, &DMA_InitStructure);// 3. 使能DMADMA_Cmd(DMA1_Channel1, ENABLE);// 4. 配置ADC使用DMAADC_DMACmd(ADC1, ENABLE);
}// 在主程序中初始化后,ADC会自动连续转换并将结果存入ADC_Values数组
主程序示例
int main(void)
{// 初始化系统时钟等SystemInit();// 初始化ADCADC1_Init();ADC1_DMA_Init(); // 如果使用DMA方式// 启动ADC转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);while(1){// 如果使用轮询方式// ADC_ReadAllChannels();// 处理ADC值// ADC_Values[0] 对应PA0// ADC_Values[1] 对应PA1// ...// ADC_Values[4] 对应PA4// 可以添加延时或其他处理Delay_ms(100);}
}
注意事项
- 确保输入电压不超过3.3V,否则可能损坏MCU
- 对于高精度应用,考虑添加参考电压电路
- 采样时间应根据信号源阻抗调整,高阻抗源需要更长的采样时间
- 在噪声环境中,考虑添加滤波电容和软件滤波算法
- DMA方式效率更高,适合需要连续采集的应用
以上代码提供了STM32F103上使用PA0-PA4进行多路ADC采集的基本框架,您可以根据具体应用需求进行调整和优化。