STM32外设介绍4(ADC)
在嵌入式系统开发中,ADC(Analog to Digital Converter,模数转换器) 是将模拟信号转换为数字信号的关键模块。STM32 系列微控制器集成了高性能的 ADC,广泛应用于电压采样、传感器读取、温度测量等场景。
本文将介绍 STM32 的 ADC 模块基本原理、配置流程,并以实际案例说明如何实现 MD(Measure and Display)输出,即采样并实时显示数据。
📌 一、ADC 模块简介
STM32 的 ADC 具有以下典型特性:
多通道输入(可达 16 通道以上)
支持 6~16 位分辨率(依芯片型号而定)
采样率高(通常可达百万次/秒)
支持连续转换、扫描模式、DMA传输等
可与内部温度传感器、电压参考等配合使用
⚙️ 二、ADC 工作原理
采样保持:将模拟输入电压暂时存储在采样电容上。
量化转换:将模拟电压转换为数字值,依据分辨率输出。
数据读取:通过寄存器、DMA 或中断方式读取转换结果。
🧩 三、ADC 初始化配置流程(以 STM32CubeMX 为例)
使能 ADC 时钟
配置 ADC 分辨率与采样时间
选择通道(如 PA0 = ADC_IN0)
配置触发模式(软件触发或定时器触发)
启用中断或 DMA(可选)
在主程序中启动 ADC 并读取值
本节将以 STM32F103 系列 MCU 为例,介绍如何使用 HAL 库配置 ADC 实现模拟电压采样,并通过串口(USART1)将采样值转换为电压后实时输出(Measure & Display,简称 MD 输出)。
📌 一、硬件连接
模拟输入:PA1 接电压源(如电位器中间端)
串口输出:PA9(TX) → USB 转串口 → 电脑串口工具查看
⚙️ 二、CubeMX 配置步骤
RCC 选择 HSE 或 HSI 启动系统时钟
![图片[1] - STM32外设介绍4(ADC) - 宋马](https://pic.songma.com/blogimg/20250804/cddace2c46834bff87b1b09d4954ea34.png)

ADC1
启用 ADC1
添加通道:IN1(PA1)
采样时间建议设置为 71.5 cycles 或更长

USART1
设置为异步模式(Async)
波特率:115200
PA1 设置为 Analog 模式
PA9 设置为 USART1_TX
在这里插入图片描述

生成工程,选用 HAL 库 + MDK-ARM/Keil
🧩 三、ADC采样+串口输出代码(main.c)
#include "main.h"
#include <stdio.h>
ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart1;
char msg[64];
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
HAL_ADC_Start(&hadc1); // 启动ADC
while (1)
{
HAL_ADC_PollForConversion(&hadc1, 10); // 等待转换完成
uint16_t adc_val = HAL_ADC_GetValue(&hadc1); // 读取ADC值
float voltage = (3.3f / 4096.0f) * adc_val; // 转换为电压值
sprintf(msg, "ADC: %d, Voltage: %.2f V
", adc_val, voltage);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
HAL_Delay(500); // 每500ms输出一次
}
}
//ADC初始化如下
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {
0};
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
sConfig.Channel = ADC_CHANNEL_1; // PA1
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
调试结果输出如下:
ADC: 2048, Voltage: 1.65 V
ADC: 2080, Voltage: 1.68 V
✅ ADC 采样相已关注意事项
GPIO 配置必须是 Analog 模式
示例:PA1 用作 ADC_IN1 时,CubeMX 中必须设置为 Analog,否则采样结果会异常(常为 0)。
采样时间设置要够长
默认 1.5cycles 对高阻抗信号(如电位器)采样不准确,建议设置为 71.5cycles 或更高,如:
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
采样时间越长,输入信号稳定性越高。
ADC参考电压 = VDDA
STM32F1 系列的 ADC 默认参考电压为 VDDA(一般为 3.3V),若电源不稳定会导致转换结果不准。
建议使用外部稳压 LDO 提供稳定 3.3V 给 MCU。
禁止对模拟输入引脚使用上拉/下拉电阻
Analog 模式下,不应启用内部上下拉,否则可能干扰模拟输入。
✅ 软件使用注意事项
Poll方式 vs. DMA/中断
初学者推荐使用 HAL_ADC_PollForConversion() 阻塞式采样;
对于高频采样(如 >1kHz),建议使用 DMA 或 ADC中断 方式,减轻主循环负担。
串口波特率
输出太快会导致串口拥堵(特别是调试时),建议使用 115200 波特率以上;
串口发送前应检查是否完成上一次传输(阻塞模式自带等待)。
浮点计算与效率
将 ADC 值转换为电压需要 float 运算,若不需要高精度可直接使用定点计算优化效率:
voltage = (3300 * adc_val) / 4096; // 单位: mV
✅ 电路设计注意事项
信号源阻抗不能太大
STM32 ADC 内部有采样电容,若外部电路阻抗太高,会导致电压不能快速充满,采样值偏差大;
若接电位器或传感器,推荐使用**缓冲运放(如LM358)**隔离。
抗干扰处理
ADC 输入应远离高频/高电流走线;
电源部分加入 0.1uF + 10uF 去耦电容;
可在输入端加 RC 滤波(如 1kΩ + 0.1uF)。
✅ 调试与验证
校验 ADC 精度
可用已知电压源测试 ADC 线性是否正常;
实际电压值 ≈ ADC值 × (3.3 / 4096),误差应<1%。
















暂无评论内容