STM32外设介绍4(ADC)

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) - 宋马

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%。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容