【STM32】ADC的认识和使用——以STM32F407为例
【STM32】ADC的认识和使用——以STM32F407为例
文章目录
- 【STM32】ADC的认识和使用——以STM32F407为例
- 一、ADC简介
- ADC特性参数
- STM32F407 的 ADC 主要特性
- ADC框图
- ① 输入电压
- ② 输入通道
- ③ 转换顺序
- ⑤ 转换时间
- ⑦ 中断
- DMA请求(==只适用于规则组==)
- ADC工作模式
- 单次转换模式和连续转换模式
- 扫描模式
- 不同模式组合的作用
- 二、ADC配置
- 单通道ADC采集配置步骤
- 单通道ADC采集(DMA读取)配置步骤
- 关键函数和结构体:
- 三、注意事项——ADC采样率与转换模式的关系
- 在非连续模式下:
- 但如果我们在连续转换模式下:
- ADC 自身采样率的计算
一、ADC简介
ADC 即模拟数字转换器,英文详称 Analog-to-digital converter,可以将外部的模拟信号转换为数字信号。
ADC特性参数
- 分辨率:表示ADC能辨别的最小模拟量,用二进制位数表示,比如:8、10、12、16位等
- 转换时间:表示完成一次A/D转换所需要的时间,转换时间越短,采样率就可以越高
- 精度:最小刻度基础上叠加各种误差的参数,精度受ADC性能、温度和气压等影响
- 量化误差:用数字量近似表示模拟量,采用四舍五入原则,此过程产生的误差为量化误差
STM32F407 的 ADC 主要特性
STM32F4xx 系列芯片拥有 3 个 ADC,这些 ADC 可以独立使用,其中 ADC1 和 ADC2 还可以组成双重模式(提高采样率)。 STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 19 个通道,可测量 16 个外部和 2 个内部信号源和 Vbat 通道的信号 ADC 中的各个通道的A/D 转换可以单次、连续、扫描或间断模式执行。
-
可配置 12 位、 10 位、 8 位或 6 位分辨率;
-
转换结束、注入转换结束和发生模拟看门狗事件时产生中断
-
单次和连续转换模式
-
自校准
-
带内嵌数据一致性的数据对齐
-
采样间隔可以按通道分别编程
-
规则转换和注入转换均有外部触发选项
-
间断模式
-
双重模式(带 2 个或以上 ADC 的器件)
-
ADC 转换时间: 最大转换速率为 2.4MHz,转换时间为 0.41us
-
ADC 供电要求: 2.4V 到 3.6V
-
ADC 输入范围: VREF–≤VIN≤VREF+13、规则通道转换期间有 DMA 请求产生
ADC框图
① 输入电压
ADC 输入范围 VREF– ≤ VIN ≤ VREF+
对于探索者V3开发板,VDDA 和 VREF+接 VCC3.3,而 VSSA和 VREF-是接地,所以 ADC 的输入范围即 0~3.3V
② 输入通道
ADC1 有 16 个外部通道和 3 个内部通道,而 ADC2和 ADC3 只有 16 个外部通道。 ADC1 的外部通道是通道 17、通道 18 和通道 19,分别连接到内部温度传感器、内部Vrefint和Vbat。
ADC1 | IO | ADC2 | IO | ADC3 | IO |
---|---|---|---|---|---|
通道 0 | PA0 | 通道 0 | PA0 | 通道 0 | PA0 |
通道 1 | PA1 | 通道 1 | PA1 | 通道 1 | PA1 |
通道 2 | PA2 | 通道 2 | PA2 | 通道 2 | PA2 |
通道 3 | PA3 | 通道 3 | PA3 | 通道 3 | PA3 |
通道 4 | PA4 | 通道 4 | PA4 | 通道 4 | PF6 |
通道 5 | PA5 | 通道 5 | PA5 | 通道 5 | PF7 |
通道 6 | PA6 | 通道 6 | PA6 | 通道 6 | PF8 |
通道 7 | PA7 | 通道 7 | PA7 | 通道 7 | PF9 |
通道 8 | PB0 | 通道 8 | PB0 | 通道 8 | PF10 |
通道 9 | PB1 | 通道 9 | PB1 | 通道 9 | PF3 |
通道 10 | PC0 | 通道 10 | PC0 | 通道 10 | PC0 |
通道 11 | PC1 | 通道 11 | PC1 | 通道 11 | PC1 |
通道 12 | PC2 | 通道 12 | PC2 | 通道 12 | PC2 |
通道 13 | PC3 | 通道 13 | PC3 | 通道 13 | PC3 |
通道 14 | PC4 | 通道 14 | PC4 | 通道 14 | PF4 |
通道 15 | PC5 | 通道 15 | PC5 | 通道 15 | PF5 |
③ 转换顺序
- 当任意 ADCx 多个通道以任意顺序进行一系列转换就诞生了成组转换,这里就有两种成组转换类型:规则组和注入组。
- 注入组转换可以打断规则组的转换。假如在规则组转换过程中,注入组启动,那么注入组被转换完成之后,规则组才得以继续转换。
④ 触发源
⑤ 转换时间
对于STM32F407,如果ADC的分辨率配置为12位分辨率,ADC的转换时间计算公式为**TCONV = 采样时间 + 12 个周期**
,采样时间可以由用户配置,不同分辨率的转换时间计算公式是不一样的
注意:STM32F4的ADC时钟频率最大不超过36MHZ

⑥ 数据寄存器
⑦ 中断
F1/F4/F7系列ADC中断事件汇总表:
中断事件 | 事件标志 | 使能控制位 |
---|---|---|
规则通道转换结束 | EOC | EOCIE |
注入通道转换结束 | JEOC | JEOCIE |
设置了模拟看门狗状态位 | AWD | AWDIE |
溢出(F1没有) | OVR | OVRIE |
DMA请求(只适用于规则组)
规则组每个通道转换结束后,除了可以产生中断外,还可以产生DMA请求,我们利用DMA及时把转换好的数据传输到指定的内存里,防止数据被覆盖。
ADC工作模式
单次转换模式和连续转换模式
转换组/转换模式 | 单次转换模式(只触发一次转换) | 连续转换模式(自动触发下一次转换) 注意:只有规则组才能触发该模式 |
---|---|---|
规则组 | 转换结果被储存在ADC_DR EOC(转换结束)标志位被置1 如果设置了EOCIE位,则产生中断 然后ADC停止 | 转换结果被储存在ADC_DR EOC(转换结束)标志位被置1 如果设置了EOCIE位,则产生中断 |
注入组 | 转换结果被储存在ADC_DRJx JEOC(转换结束)标志位被置1 如果设置了JEOCIE位,则产生中断 然后ADC停止 | 转换结果被储存在ADC_DRJx JEOC(转换结束)标志位被置1 如果设置了JEOCIE位,则产生中断 自动注入:将JAUTO位置1 |
扫描模式
关闭扫描模式 | 使用扫描模式 |
---|---|
ADC只转换ADC_SQRx或ADC_JSQR选中的第一个通道进行转换 | ADC会扫描所有被ADC_SQRx或ADC_JSQR选中的所有通道 |
不同模式组合的作用
单次转换模式(不扫描) | 只转换一个通道,而且是一次,需等待下一次触发 |
---|---|
单次转换模式(扫描) | ADC_SQRx 和ADC_JSQR 选中的所有通道都转换一次 |
连续转换模式(不扫描) | 只会转换一个通道,转换完后会自动执行下一次转换 |
连续转换模式(扫描) | ADC_SQRx 和ADC_JSQR 选中的所有通道都转换一次,并自动进入下一轮转换 |
二、ADC配置
单通道ADC采集配置步骤
1,配置ADC工作参数、ADC校准 HAL_ADC_Init()、HAL_ADCEx_Calibration_Start()
2,ADC MSP初始化 HAL_ADC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置ADC相应通道相关参数 HAL_ADC_ConfigChannel()
4,启动A/D转换 HAL_ADC_Start()
5,等待规则通道转换完成 HAL_ADC_PollForConversion()
6,获取规则通道A/D转换结果 HAL_ADC_GetValue()
单通道ADC采集(DMA读取)配置步骤
1,初始化DMA HAL_DMA_Init()
2,将DMA和ADC句柄联系起来 __HAL_LINKDMA()
3,配置ADC工作参数、ADC校准 HAL_ADC_Init()、HAL_ADCEx_Calibration_Start()
4,ADC MSP初始化 HAL_ADC_MspInit() 配置NVIC、CLOCK、GPIO等
5,配置ADC相应通道相关参数 HAL_ADC_ConfigChannel()
6,使能DMA数据流传输完成中断 HAL_NVIC_SetPriority()、HAL_NVIC_EnableIRQ()
7,编写DMA数据流中断服务函数 DMAx_Channely_IRQHandler()
8,启动DMA,开启传输完成中断 HAL_DMA_Start_IT()
9,触发ADC转换,DMA传输数据 HAL_ADC_Start_DMA()
关键函数和结构体:
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc);//配置ADC工作参数typedef struct
{
ADC_TypeDef *Instance; /* ADC 寄存器基地址 */
ADC_InitTypeDef Init; /* ADC 参数初始化结构体变量 */
__IO uint32_t NbrOfCurrentConversionRank; /* 当前转换等级的 ADC 数 */
DMA_HandleTypeDef *DMA_Handle; /* DMA 配置结构体 */
HAL_LockTypeDef Lock; /* ADC 锁定对象 */
__IO uint32_t State; /* ADC 工作状态 */
__IO uint32_t ErrorCode; /* ADC 错误代码 */
}ADC_HandleTypeDef;typedef struct {
uint32_t ClockPrescaler; /* 设置预分频系数,即 PRESC[3:0]位 */
uint32_t Resolution; /* 配置 ADC 的分辨率 */
uint32_t ScanConvMode; /* 扫描模式 */
uint32_t EOCSelection; /* 转换完成标志位 */
FunctionalState ContinuousConvMode; /* 开启连续转换模式否则就是单次转换模式 */
uint32_t NbrOfConversion; /* 设置转换通道数目 */
FunctionalState DiscontinuousConvMode; /* 单次转换模式选择 */
uint32_t NbrOfDiscConversion; /* 单次转换通道的数目 */
uint32_t ExternalTrigConv; /* ADC 外部触发源选择 */
uint32_t ExternalTrigConvEdge; /* ADC 外部触发极性*/
FunctionalState DMAContinuousRequests; /* DMA 转换请求模式*/
} ADC_InitTypeDef;
-
ClockPrescaler: ADC 预分频系数选择,可选的分频系数为 2、 4、 6、 8。 由于 ADC 最大时钟不得超过 36Mhz,我们这里配置 4 分频,即 ADC 的时钟频率为: 84 / 4 = 21Mhz。
-
Resolution:配置 ADC 的分辨率,可选的分辨率有 12 位、 10 位、 8 位和 6 位。分辨率越高,转换数据精度越高,转换时间也越长;反之分辨率越低,转换数据精度越低,转换时间也越短。
-
ScanConvMode:配置是否使用扫描。如果是单通道转换使用 ADC_SCAN_DISABLE,如果是多通道转换使用 ADC_SCAN_ENABLE。
-
EOCSelection:可选参数为 ADC_EOC_SINGLE_CONV 和 ADC_EOC_SEQ_CONV, 指定转换结束时是否产生 EOS 中断或事件标志。
-
ContinuousConvMode:可选参数为 ENABLE 和 DISABLE,配置自动连续转换还是单次转换。使用 ENABLE 配置为使能自动连续转换;使用 DISABLE 配置为单次转换,转换一次后停止需要手动控制才重新启动转换。
-
NbrOfConversion:设置常规转换通道数目, 范围是: 1~16。
-
DiscontinuousConvMode:配置是否使用不连续的采样模式,比如要转换的通道有 1、 2、 5、7、 8、 9,那么第一次触发会进行通道 1 与通道 2,下次触发就是转换通道 5 与通道 7,这样不连续的转换,依次类推。此参数只有将 ScanConvMode 使能,还有 ContinuousConvMode失能的情况下才有效,不可同时使能。
-
NbrOfDiscConversion: 不连续采样通道数。
-
ExternalTrigConv:外部触发方式的选择,如果使用软件触发,那么外部触发会关闭。
-
ExternalTrigConvEdge:外部触发极性选择,如果使用外部触发,可以选择触发的极性,可选有禁止触发检测、上升沿触发检测、下降沿触发检测以及上升沿和下降沿均可触发检测。
-
DMAContinuousRequests:指定 DMA 请求是否以一次性模式执行(当达到转换次数时, DMA传输停止)或在连续模式下(DMA 传输无限制,无论转换的数量)。注:在连续模式下, DMA 必须配置为循环模式。否则,当达到 DMA 缓冲区最大指针时将触发溢出。注意:当常规组和注入组都没有转换时(禁用 ADC,或启用 ADC,没有连续模式或可以启动转换的外部触发器),必须修改此参数。该参数可设置为“启用”或“禁用”。
HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc);//ADC校准 HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc,ADC_ChannelConfTypeDef *sConfig);//配置ADC相应通道的相关参数typedef struct {
uint32_t Channel; /* ADC 转换通道*/
uint32_t Rank; /* ADC 转换顺序 */
uint32_t SamplingTime; /* ADC 采样周期 */
uint32_t Offset; /* ADC 偏移量 */
} ADC_ChannelConfTypeDef;HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc);//启动A/D转换 HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc,uint32_t Timeout);//等待规则通道转换完成 uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc);//获取规则通道A/D转换结果
三、注意事项——ADC采样率与转换模式的关系
这一部分是我在学习的时候产生的困惑和解决方法
当我们使用的是非连续转换模式,在每一次ADC转换之后ADC的下一次转换就会停止,此时我们需要再给ADC一个触发源信号,比如说TIM3定时器的上升沿信号,ADC才会进行下一次转换,如果我们设置的TIM3的频率小于ADC自身的采样率,那么实际上ADC的采样率应该是TIM3定时器的频率,而不是由于设置ADC的转换时间以及ADC的时钟频率得到的ADC自身采样率
在非连续模式下:
- ADC 的实际采样率 = 触发源信号的频率(例如 TIM3 输出频率)。
- TIM3 的频率决定了 ADC 的实际工作速率,而 ADC 的自身硬件采样率仅表示其在理想条件下的最高采样能力。
但如果我们在连续转换模式下:
-
自动触发下一次转换:
- 在连续模式下,ADC 会在每次完成一次转换后,立即自动启动下一次转换,无需外部触发信号。
- 这种模式适合高采样率、连续采样的应用,比如波形采集或快速信号监测。
-
采样率由硬件决定:
- 在这种模式下,ADC 的实际采样率 = ADC 自身的最大采样速度,由以下因素决定:
- ADC 时钟频率(
f_ADC
)。 - 每次采样的时间(由采样时间和转换时间决定)。
- ADC 时钟频率(
- 在这种模式下,ADC 的实际采样率 = ADC 自身的最大采样速度,由以下因素决定:
ADC 自身采样率的计算
ADC 的每次采样需要两个阶段:
- 采样阶段:
- 采样阶段需要等待输入信号电容充电完成,其时间由
ADC_SampleTime
配置决定(常见选项包括 3、15、28、56、84、112、144 或 480 个时钟周期)。 - 采样时间越长,信号精度越高,但采样速率越低。
- 采样阶段需要等待输入信号电容充电完成,其时间由
- 转换阶段:
- 将模拟信号转换为数字值所需的时间,这通常是 12 位分辨率转换对应的时钟周期数(ADC 在 12 位分辨率下需要 12 个时钟周期)。这个需要通过查阅芯片的数据手册,每种芯片不一样
总之:
在连续转换模式下,ADC 的实际采样率完全由硬件配置决定。采样率与采样时间、转换时间和 ADC 时钟频率密切相关。如果采样速率需要与特定信号的时序同步,则应切换到非连续模式,并通过外部触发信号(如定时器)控制采样。