STM32 单片机 - ADC
一、ADC 介绍
ADC (analog-to-digital converter):模数转换器 - 将模拟信号转换为数字信号
模拟信号:连续周期变化的信号,在时间和数值上都是连续变化的物理量。
数字信号:以离散的 0 和 1 组成的信号,在时间和数值上都是离散的物理量。
![]()
图 1 模拟信号和数字信号
ADC 一般使用在电路中电流和电压的检测,以及传感器中数据的转换
STM32U575RIT6 可以使用 ADC1 和 ADC4 两个外设控制器进行模数转换
二、ADC1 和 ADC4
2.1 模数转换原理

ADC 的采样位数:本质是采样精度,是将模拟信号转化为数字信号后的位数;
ADC1 转化后的数字信号是 14 位,ADC4 转化后的数字信号是 12 位
数据寄存器:存储转换后的数字信号
![]()
图 3 逐次逼近法原理图 ![]()
图 4 逐次逼近法原理 ADC 转化使用的是 逐次逼近法
逐次逼近法:循环使用二分查找(折半查找)
AD4 的转化数字信号时 12 位,转换后的数字信号范围时 0 ~ 2¹²-1
2.2 模数转换公式
以 电压模拟信号转换 -> 电压数字信号 为例,使用 12 位的 ADC4
ADC转换后的数字信号 = 4096 / 3.3v * 1.2v
4096:采样位数的 ADC 最大转化范围(2¹²=4096,2¹⁴=16384)
3.3v:参考电压 / 供电电压
1.2v:待测电压
待测电压的数字信号 = (2^(ADC的采样位数) / 参考电压) * 待测电压的模拟信号
2.3 采样时机和偏移补偿

采样时机指的是ADC的采样保持电路在何时对模拟输入信号进行“采样”(捕获瞬时电压值)的精确时间点。
偏移补偿,也称为失调电压校准,目的是消除ADC输出代码中存在的固定的、系统的直流偏差。如果ADC采样发生偏移,此时采样得到的数据可能不是很准确,就需要使用硬件提供的偏移补偿机制(校准机制)初始化采样时机。
三、ADC 采样模式
3.1 ADC1 的内部框图


3.2 ADC4 内部框图


3.3 ADC 的转化模式(采样模式)

单通道单次转化模式:
只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,并只转换一次就结束。
单通道连续转换模式:
只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,结束一次后,自动进行下一次转化。
单通道连续转化模式 = while(1) + 单通道单次转化模式
多通道单次转化模式:
使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,每个通道只转换一次。
多通道连续转换模式:
使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,所有通道转化完后,回到初始通道重新依次转换。
多通道连续转化模式 = while(1) + 多通道单次转化模式
间隔转化模式(间隔触发模式):
给对应通道一个触发信号(触发源)后,ADC 模数转换器开始一次对通道中的模拟信号转换为数字信号。
ADC的转化模式:独立模式(单通道模式)、扫描模式(多通道模式)、触发模式
四、分析电路图

拓展板电压检测引脚:PB1
五、CubeMX 配置


- ADCs_Common_Settings(ADC 通用设置)
- Mode(模式):Independent mode(独立模式(每个通道都是独立的))
- ADC_Settings(ADC 设置)
- Clock Prescaler(时钟分频):Asynchronous clock mode divided by 1(时钟分频(时钟频率 -> 影响 ADC 模数转化的速率))
- Resolution(采样精度):ADC 12 - bit resolution(采样精度(转化后的数字信号的位数):12 位)
- Data Alignment(数据对齐方式):Right alignment(数据对齐方式:右对齐)
- Sequencer(序列器):Sequencer set to not fully configurable
- Scan Conversion Mode(输入转化模式):Forward(输入转化模式:标准模式(标准转化速率模式))
- Continuous Conversion Mode(连续转化模式):Disabled
- Discontinuous Conversion Mode(不连续转化模式):Disabled
- DMA Continuous Requests(DMA 连续请求):Disabled
- End Of Conversion Selection(转换结束选择):End of single conversion
- Overrun behaviour(数据保存的机制):Overrun data preserved(数据保存的机制:转化后的数字信号被存储到数据寄存器中可以使用追加 / 覆盖的方式)
- Low Power Auto Wait(低功耗自动等待):Disabled
- Low Power Auto Off(低功耗自动关闭):Low power disabled and auto off disabled
- SamplingTime Common 1(通用采样时间 1):1.5 Cycles(通用的采样时间:1.5 轮转化一次,轮的具体时间需要根据时钟频率来计算 理论上,采样时间越长,采样得到的数据越准确)
- SamplingTime Common 2(通用采样时间 2):1.5 Cycles
- Trigger Frequency(触发频率):Low frequency
- External Trigger Conversion Source(外部触发转换源):Regular Conversion launched by software(使用间隔触发模式时,需要设置)
- External Trigger Conversion Edge(外部触发转换沿):None
- Oversampling Mode(过采样模式):Disabled
- Sampling Time(采样时间):Sampling time common 1(使用采样时间 1)
六、API 接口
ADC 采样和转化流程:
- 开启 ADC 采样校准模式
- 开启 ADC 采样转化功能
- 等待采样+转化结束,数字信号被存放到数据寄存器中
- 从数据寄存器中读取数字信号
- 通过模数转化公式,将数字信号转换为模拟信号,并在串口终端打印
注意:ADC 的校准采样必须在开启采样前或者关闭采样后
6.1 HAL_ADC_Start 函数
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)
功能:
HAL库提供的用于开启ADC采样转化功能的函数
参数:
hadc:ADC4外设控制器的句柄
返回值:
函数执行成功,返回HAL_OK
函数执行失败,返回错误码
6.2 HAL_ADC_GetValue 函数
uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc)
功能:
HAL库提供的用于获取转化完毕的数字信号的函数
参数:
hadc:ADC4外设控制器的句柄
返回值:
返回成功获取的数字信号
6.3 HAL_ADC_PollForConversion 函数
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
功能:
HAL库提供的用于阻塞等待ADC采样+转化完毕,数据被存放到数据寄存器中的函数
参数:
hadc:ADC4外设控制器的句柄 Timeout:超时检测时间,当前函数的最大阻塞时间
返回值:
当ADC采样+转化数据完毕后,表示这个函数执行成功,函数执行成功,返回HAL_OK
当ADC采样+转化数据没结束时,此时这个函数处于阻塞状态
函数执行失败,返回错误码
HAL_MAX_DELAY 宏
#define HAL_MAX_DELAY 0xFFFFFFFFU
6.4 HAL_ADC_Stop 函数
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc)
功能:
HAL库提供的用于关闭ADC采样转化功能的函数
参数:
hadc:ADC4外设控制器的句柄
返回值:
函数执行成功,返回HAL_OK
函数执行失败,返回错误码
6.5 HAL_ADCEx_Calibration_Start 校准采样函数
HAL_StatusTypeDef HAL_ADCEx_Calibration_Start (ADC_HandleTypeDef *hadc, uint32_t CalibrationMode, uint32_t SingleDiff)
功能:
HAL库提供的用于校准ADC采样的函数(此函数只需要开启一次即可)
参数:
hadc:ADC4外设控制器的句柄
CalibrationMode:校准模式的设置
ADC_CALIB_OFFSET 偏移量校准方式(最基础的)
ADC_CALIB_OFFSET_LINEARITY 硬件线性化校准(高级的) 线性化校准比偏移量校准更准确,一般使用一些高精度仪器上
SingleDiff:输入的模拟信号的选择
ADC_SINGLE_ENDED:输入单端信号(一个信号就代表一个电信号) ADC_DIFFERENTIAL_ENDED:输入差分信号(两个信号代表一个电信号)
返回值:
函数执行成功,返回HAL_OK
函数执行失败,返回错误码
七、代码编写
7.1 单通道单次转换模式
1)main.c 重写 fputc 函数
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE* stream)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,5);return ch;
}
/* USER CODE END 0 */
八、DMA 介绍
DMA (General purpose direct memory access controller):通用可编程直接内存访问控制器
内存:广义的内存,包括虚拟内存地址和物理内存地址
DMA 本质是硬件缓冲区(FIFO)
DMA 的作用
减轻 CPU 的压力,将简单的数据存储工作交给 DMA 去做,让 CPU 只负责逻辑处理和数据处理。
![]()
图 1 DMA 图示
1. GPDMA 支持 16 个独立通道,每个通道都可以用来独立暂存数据