当前位置: 首页 > web >正文

【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 转换可以单次、连续、扫描或间断模式执行。

  1. 可配置 12 位、 10 位、 8 位或 6 位分辨率;

  2. 转换结束、注入转换结束和发生模拟看门狗事件时产生中断

  3. 单次和连续转换模式

  4. 自校准

  5. 带内嵌数据一致性的数据对齐

  6. 采样间隔可以按通道分别编程

  7. 规则转换和注入转换均有外部触发选项

  8. 间断模式

  9. 双重模式(带 2 个或以上 ADC 的器件)

  10. ADC 转换时间: 最大转换速率为 2.4MHz,转换时间为 0.41us

  11. ADC 供电要求: 2.4V 到 3.6V

  12. 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

ADC1IOADC2IOADC3IO
通道 0PA0通道 0PA0通道 0PA0
通道 1PA1通道 1PA1通道 1PA1
通道 2PA2通道 2PA2通道 2PA2
通道 3PA3通道 3PA3通道 3PA3
通道 4PA4通道 4PA4通道 4PF6
通道 5PA5通道 5PA5通道 5PF7
通道 6PA6通道 6PA6通道 6PF8
通道 7PA7通道 7PA7通道 7PF9
通道 8PB0通道 8PB0通道 8PF10
通道 9PB1通道 9PB1通道 9PF3
通道 10PC0通道 10PC0通道 10PC0
通道 11PC1通道 11PC1通道 11PC1
通道 12PC2通道 12PC2通道 12PC2
通道 13PC3通道 13PC3通道 13PC3
通道 14PC4通道 14PC4通道 14PF4
通道 15PC5通道 15PC5通道 15PF5
③ 转换顺序
  • 当任意 ADCx 多个通道以任意顺序进行一系列转换就诞生了成组转换,这里就有两种成组转换类型:规则组和注入组。
  • 注入组转换可以打断规则组的转换。假如在规则组转换过程中,注入组启动,那么注入组被转换完成之后,规则组才得以继续转换。

在这里插入图片描述

④ 触发源

⑤ 转换时间

对于STM32F407,如果ADC的分辨率配置为12位分辨率,ADC的转换时间计算公式为**TCONV = 采样时间 + 12 个周期**

,采样时间可以由用户配置,不同分辨率的转换时间计算公式是不一样的

在这里插入图片描述

注意:STM32F4的ADC时钟频率最大不超过36MHZ

image-20250219202439825

⑥ 数据寄存器

⑦ 中断

F1/F4/F7系列ADC中断事件汇总表:

中断事件事件标志使能控制位
规则通道转换结束EOCEOCIE
注入通道转换结束JEOCJEOCIE
设置了模拟看门狗状态位AWDAWDIE
溢出(F1没有)OVROVRIE
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;
  1. ClockPrescaler: ADC 预分频系数选择,可选的分频系数为 2、 4、 6、 8。 由于 ADC 最大时钟不得超过 36Mhz,我们这里配置 4 分频,即 ADC 的时钟频率为: 84 / 4 = 21Mhz。

  2. Resolution:配置 ADC 的分辨率,可选的分辨率有 12 位、 10 位、 8 位和 6 位。分辨率越高,转换数据精度越高,转换时间也越长;反之分辨率越低,转换数据精度越低,转换时间也越短。

  3. ScanConvMode:配置是否使用扫描。如果是单通道转换使用 ADC_SCAN_DISABLE,如果是多通道转换使用 ADC_SCAN_ENABLE。

  4. EOCSelection:可选参数为 ADC_EOC_SINGLE_CONV 和 ADC_EOC_SEQ_CONV, 指定转换结束时是否产生 EOS 中断或事件标志。

  5. ContinuousConvMode:可选参数为 ENABLE 和 DISABLE,配置自动连续转换还是单次转换。使用 ENABLE 配置为使能自动连续转换;使用 DISABLE 配置为单次转换,转换一次后停止需要手动控制才重新启动转换。

  6. NbrOfConversion:设置常规转换通道数目, 范围是: 1~16。

  7. DiscontinuousConvMode:配置是否使用不连续的采样模式,比如要转换的通道有 1、 2、 5、7、 8、 9,那么第一次触发会进行通道 1 与通道 2,下次触发就是转换通道 5 与通道 7,这样不连续的转换,依次类推。此参数只有将 ScanConvMode 使能,还有 ContinuousConvMode失能的情况下才有效,不可同时使能。

  8. NbrOfDiscConversion: 不连续采样通道数。

  9. ExternalTrigConv:外部触发方式的选择,如果使用软件触发,那么外部触发会关闭。

  10. ExternalTrigConvEdge:外部触发极性选择,如果使用外部触发,可以选择触发的极性,可选有禁止触发检测、上升沿触发检测、下降沿触发检测以及上升沿和下降沿均可触发检测。

  11. 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 的自身硬件采样率仅表示其在理想条件下的最高采样能力。
但如果我们在连续转换模式下:
  1. 自动触发下一次转换:

    • 在连续模式下,ADC 会在每次完成一次转换后,立即自动启动下一次转换,无需外部触发信号。
    • 这种模式适合高采样率、连续采样的应用,比如波形采集或快速信号监测。
  2. 采样率由硬件决定:

    • 在这种模式下,ADC 的实际采样率 = ADC 自身的最大采样速度,由以下因素决定:
      • ADC 时钟频率f_ADC)。
      • 每次采样的时间(由采样时间和转换时间决定)。
ADC 自身采样率的计算

ADC 的每次采样需要两个阶段:

  1. 采样阶段:
    • 采样阶段需要等待输入信号电容充电完成,其时间由 ADC_SampleTime 配置决定(常见选项包括 3、15、28、56、84、112、144 或 480 个时钟周期)。
    • 采样时间越长,信号精度越高,但采样速率越低。
  2. 转换阶段:
    • 将模拟信号转换为数字值所需的时间,这通常是 12 位分辨率转换对应的时钟周期数(ADC 在 12 位分辨率下需要 12 个时钟周期)。这个需要通过查阅芯片的数据手册,每种芯片不一样

总之:
在连续转换模式下,ADC 的实际采样率完全由硬件配置决定。采样率与采样时间、转换时间和 ADC 时钟频率密切相关。如果采样速率需要与特定信号的时序同步,则应切换到非连续模式,并通过外部触发信号(如定时器)控制采样。

http://www.xdnf.cn/news/3366.html

相关文章:

  • 分布式锁的几种实现
  • 使用HunyuanVideo搭建文本生视频大模型
  • OpenSSL应用实践:嵌入式数据安全实战指南
  • 使用Node编写轻量级后端快速入门
  • 极简GIT使用
  • 【内存管理】对象树(内存管理)
  • (持续更新)Ubuntu搭建LNMP(Linux + Nginx + MySQL + PHP)环境
  • DeepSeek生成Word文档的创新路径与应用
  • 【计算机视觉】三维视觉:Nerfstudio:模块化神经辐射场框架的技术突破与实战指南
  • 操作系统OS是如何指挥外围设备的呢?
  • MySQL 服务搭建
  • Leetcode刷题记录25——合并区间
  • MySQL与分布式架构的碰撞
  • 使用MGeo模型高精度实现文本中地址识别
  • 题解:洛谷 CF2091E Interesting Ratio
  • Java 中使用正则表达式
  • 在Linux中,KVM和Docker在Linux虚拟化中的区别是什么?
  • 【计算机视觉】语义分割:Mask2Former:统一分割框架的技术突破与实战指南
  • Mysql常用函数解析
  • Annotate better with CVAT
  • 华为OD机试真题——斗地主之顺子(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • 《TCP/IP详解 卷1:协议》之第九章:IP选路
  • 湖仓一体化介绍
  • 数据库基本概念:数据库的定义、特点、分类、组成、作用
  • 详解TypeScript中的类型断言及其绕过类型检查机制
  • 【Vue bug】:deep()失效
  • 如何提升自我执行力?
  • 拆解 browser-use 项目——深入理解 Agent 层
  • Linux 环境下 Mysql 5.7 数据定期备份
  • Kotlin-运算符重载函数