STM32 ADC电压采集与串口显示系统
一、项目简介
基于STM32F103微控制器的ADC电压采集系统,实现外部模拟电压信号的实时采集、数字化处理,并通过串口通信将电压值传输到上位机显示。系统采用标准库开发,包含完整的硬件初始化和数据处理流程。
二、核心代码模块
1. 主程序框架 (main.c)
c
int main(void)
{
float VolValue = 0.00; // 存储转换后的电压值
u32 ticks = 0; // 延时计数器
// 系统初始化四部曲
RCC_Configuration(); // 时钟配置
GPIO_Configuration(); // 引脚配置
USART_Configuration(); // 串口配置
ADC_Configuration(); // ADC配置
printf("\r\n ADC采集系统启动 \r\n");
while(1)
{
// 定时采集(约1秒间隔)
if (ticks++ >= 2000000)
{
ticks = 0;
// ADC值转换为电压:3.3V * ADC值 / 4095
VolValue = 3.3 * ADC_GetConversionValue(ADC1) / 4095.0;
printf("当前电压 = %.2f V\r\n", VolValue);
}
}
}
关键点:
- 采用简单的软件延时实现定时采集
- 电压转换公式:
实际电压 = 参考电压 × ADC值 ÷ 4095 - printf直接输出,简化调试
2. 时钟配置 (RCC_Configuration)
c
void RCC_Configuration(void)
{
// 使用外部8MHz晶振,PLL倍频到72MHz
RCC_HSEConfig(RCC_HSE_ON);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
// 开启外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |
RCC_APB2Periph_GPIOA |
RCC_APB2Periph_ADC1 |
RCC_APB2Periph_GPIOB, ENABLE);
}
3. ADC配置 (ADC_Configuration)
c
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
// ADC基础配置
ADC_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 = 1; // 1个通道
// 配置通道8(PB0引脚),采样时间55.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
// ADC校准(必须步骤)
ADC_ResetCalibration(ADC1);
ADC_StartCalibration(ADC1);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动转换
}
ADC关键参数:
- 12位分辨率,0-4095数字范围
- 参考电压:3.3V
- 采样时间:55.5周期(平衡速度与精度)
- 连续转换模式,无需重复触发
4. 串口配置 (USART_Configuration)
c
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200; // 波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位数据
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1位停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发使能
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
// printf重定向
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (u8)ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
5. GPIO配置 (GPIO_Configuration)
c
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// USART1引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA9: TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA10: RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// ADC输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PB0: ADC输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
三、硬件连接
| STM32引脚 | 功能 | 连接说明 |
|---|---|---|
| PB0 | ADC通道8 | 接被测电压(0-3.3V) |
| PA9 | USART1_TX | 接串口模块RX |
| PA10 | USART1_RX | 接串口模块TX |
| 3.3V | 参考电压 | ADC基准电压 |
| GND | 地线 | 共地连接 |
四、使用说明
1. 编译环境
- 开发工具:Keil MDK 5
- 固件库:STM32标准外设库V3.5
- 目标芯片:STM32F103C8T6
2. 操作步骤
- 按照硬件连接表连接电路
- 下载程序到STM32
- 打开串口助手(115200波特率)
- 观察电压显示
3. 输出示例
ADC采集系统启动
当前电压 = 1.65 V
当前电压 = 2.32 V
当前电压 = 0.87 V
五、性能特点
优势
- 简单易用:代码结构清晰,注释完整
- 实时性强:连续采集,实时显示
- 精度适中:12位ADC,最小分辨率0.8mV
- 易于扩展:可修改为多通道采集
局限性
- 采用软件延时,定时不够精确
- 未加入数字滤波,抗干扰能力一般
- 单通道采集,无法同时监测多路信号
六、扩展建议
软件优化
c
// 1. 增加数字滤波
float average_filter(float new_value)
{
static float buffer[10];
static int index = 0;
float sum = 0;
buffer[index++] = new_value;
if(index >= 10) index = 0;
for(int i=0; i<10; i++)
sum += buffer[i];
return sum / 10;
}
// 2. 使用定时器精确控制采样间隔
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 触发ADC采样
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
}