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

单片机ADC机理层面详细分析(一)

文章目录

  • 一、ADC硬件结构
    • 1.1 ADC硬件了解
    • 1.2 ADC组别与GPIO关系
      • 1.2.1 信号冗余与系统可靠性提升​
      • 1.2.2 多维度同步采样与分析​
      • 1.2.3 校准与诊断增强
      • 1.2.4 系统级优化与灵活性
    • 1.3 ADC转换模式
      • 1.3.1 单次转换非扫描模式
      • 1.3.2 单次转换扫描转换
    • 1.4 ADC规则组和注入组
    • 1.5 触发控制



一、ADC硬件结构

结合之前分析的GPIO章节原理,我们继续深入理解ADC片上外设,也就是GPIO的模拟输入模式的使用。

因为我们一般使用ADC采集的是电压、电流、温度、湿度等模拟连续量,因此必须使用的GPIO的模拟输入功能。

这一块也就是之前GPIO章节说明的,如果哪个GPIO口有ADC功能,那么必定在该GPIO口实现了相关的硬件电路。不然没有对应的硬件基准电压或者电流,该GPIO怎么能知道现在输入的电压或者电流是多大,没有参考谈大小都是无意义的。这也是我们现实生活中会使用海平面作为基准的原因,大家都是用海平面,那么对比出来的高低才有意义,不然我说我很高,他说他很高,那衡量的标准不一样,数据又有什么意义,这是一种思想。

1.1 ADC硬件了解

言归正传:

![[Pasted image 20250726173733.png]]

GD32F303支持3个ADC:ADC0、ADC1和ADC2

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

2、自校准;

3、可编程采样时间;

4、数据寄存器可配置数据对齐方式

5、支持规则数据转换的DMA请求,减轻CPU的负载。

模拟输入通道:

1、16路外部模拟输入通道(ADC0、ADC1)

2、ADC0包含:

1路内部温度(只能测量单片机芯片的温度,并不能测量环境温度)1路内部参考电压输入通道(VREFINT)。

转换模式:

1、单次模式和连续模式;

2、扫描模式和间断模式:

3、同步模式(适用于具有两个或多个ADC的设备)

中断的产生:(转换完成产生转换标志,基于该标志可以产生相应的中断)

规则组或注入组转换结束

ADC供电要求:2.6V到3.6V,一般电源电压为3.3V

ADC参考电压:

VREFP参考正电压连接到VDDAVREFN参考负电压连接到VSSA

所以对于模拟输入通道信号源的输入电压范围就是0到3.3V。

![[Pasted image 20250603183600.png]]

以ADC0为例:

1、GPIO后面的16

  • 表示:有16个模拟信号输入通道,使用GPIO口复用

  • 另外还有上面说的两个内部温度输入通道和参考电压输入通道。

2、触发启动

  • AD进行转换之前,需要有一个外部触发源进行触发。

  • 给一个采集信号,该触发源信号可以来自:定时器(ms、s级采集一次)、EXTI外部中断也可以触发、软件触发。

  • 其中外部中断举个例子:在本人项目开发中,有一次使用到外部中断采集某霍尔元器件信号,就是当该霍尔元器件没有触发的时候电平一直是高电平,让碰触到该霍尔元器件的时候输出为低电平,那么使用该信号端连接芯片的某个支持外部中断的GPIO口,我们可以通过该GPIO采集下降沿,从而知道霍尔元器件动作了,此时会产生一个下降沿外部中断信号,那么我们可以利用这个信号开启对应的ADC采集信号。也说明在某种想知道外界状态的时候,我们要善于使用外部中断,学会将知道的知识应用到实际的问题中。

时钟最大是40MHZ,暂时不理解时钟的使用方法。

3、AD转换器内部

  • 包含规则组和注入组。

  • 规则组:理解为程序主流程。

  • 注入组:理解为程序中断,注入组可以打断规则组转换。当执行完注入组的采集转换以后在接着进行规则组的转换。

  • 一般使用规则组就行。

  • 对于规则组16个通道共用一个数据寄存器。而注入组转换对应有4个数据寄存器。

  • 数据完成就放入到AD数据寄存器,并且转换以后会产生一个标志,进而产生中断。

4、关于中断的配置

  • 单片机片上外设内部会有一个中断输出控制,需要进行配置

  • 另外一个就是内核里面的NVIC,例如定时器的中断、NVIC中断等。相当于是一个是内部,一个是外部的。或者认为用什么就需要配置什么中断。

1.2 ADC组别与GPIO关系

![[Pasted image 20250726182430.png]]
通过该图就可以看出来,芯片不同的引脚对应不同的ADC组别,与上面介绍的ADC0、ADC1、ADC2互相印证。可以看出不同的组别包含的GPIO端口是不一样的,但是有些部分是共用的,在啰嗦一句,该芯片也只能使用使用这些GPIO作为ADC转换,其他的端口你就是想用也用不了,这是因为芯片内部的是没有硬件电路支持的。

其实这里有一个疑问:就是为什么相同的一个GPIO会被分到不同的组别,这样做有什么意义吗?

1.2.1 信号冗余与系统可靠性提升​

  1. 故障容错机制

    • 若某一ADC模块(如ADC0)因干扰或硬件故障失效,其他ADC(如ADC1/2)可继续采集同一信号源的数据(例如PA0引脚的电压),确保关键数据不丢失。

    • 应用场景:工业控制、医疗设备等对稳定性要求极高的系统。

1.2.2 多维度同步采样与分析​

  1. 同步测量需求

    • 严格时对齐采样​:多个ADC可通过硬件触发同时采集同一GPIO信号,消除时间漂移误差。

    • 应用实例​:

      • 电机控制中三相电流的瞬时同步采样,计算功率因数和谐波分量。

      • 音频系统的多声道同步采集,避免相位失真。

  2. 差异化采样配置

    • 不同ADC可独立设置采样率/分辨率(如ADC0以100ksps高速采样,ADC1以16位高精度采样),从同一信号中提取不同维度的特征。针对这里类比图像处理中不同维度的特征图,例如浅层特征、中层特征、以及深层次特征。

    • 应用实例:电池管理系统(BMS)中同时监测电池电压的快速波动(高速ADC)与长期缓慢变化(高精度ADC)。

1.2.3 校准与诊断增强

  • 交叉验证机制

    • 多个ADC同时采集同一信号,对比结果差异可实时诊断ADC的精度偏移(如温漂或老化),触发自动校准。

    • 案例:高精度电子秤中通过ADC1和ADC2的数据差异判断传感器异常。

  • 在线噪声分析

    • 比较多个ADC对同一信号的采样结果,分离系统噪声(如电源纹波)与信号真实波动。

1.2.4 系统级优化与灵活性

  • 硬件设计简化

    • 减少引脚复用冲突​:相同的GPIO映射允许设计师用单一路由走线连接到多个ADC输入,简化PCB布局。

    • 节省外部多路复用器​:无需额外芯片扩展ADC通道,降低成本与复杂度。

  • 动态资源调配

    • 在任务调度中,可根据负载将同一信号分配给空闲ADC处理,实现负载均衡(如ADC0满负荷时由ADC1接管)

关于 1.2.4 这个作用其实不太理解,因为实际的例子作为自己的支撑理解。


以GD32F303为例,就是说我可以同时开启ADC0和ADC1,对GIPO口 PA0进行同步转换,并用两个数组分别存储结果。

  1. 冗余备份系统

    • 航天设备中同时用ADC0/ADC1采集同一传感器数据,投票机制提升可靠性。
  2. 差分噪声分析

    • 对比两个ADC结果差值,分离系统噪声(如电源纹波)与信号真实波动。
  3. 同步多速率采样

    • ADC0低速采样监测长期趋势,ADC1高速捕捉瞬态脉冲(如电源故障检测)。

1.3 ADC转换模式

![[Pasted image 20250603184358.png]]

单次模式:的意思是每次转换,都需要外部触发,也就是给一个信号。

连续模式:就是在最开始的时候给出一个外部触发信号,后续就自动完成触发。

扫描模式:如果是多个通道,肯能就需要扫描模式,这样每个都能采集到。一个ADC对应多个通道,

同步模式:有时候可能需要多个ADC之间配合使用,就能用到同步模式。一般情况不需要多个ADC配合使用。例如在某个阶段需要同时使用ADC0、ADC1、ADC2互相配合,在阶段1使用ADC0、阶段二使用ADC1、阶段三使用ADC2,ADC0的数据是运行ADC1数据的基础,差不多就是这个意思,这种情况很复杂,暂时还不需要,只需要了解可能有这种场景就行

一般情况都是单独使用某个ADC。

1.3.1 单次转换非扫描模式

以规则组为例:

一定要注意规则组16个序列是共用一个AD数据寄存器。

规则组有一个转换序列,一共有16个序列,每个序列存放对应的通道,通道就理解为采集的信号来源,例如我现在使用的是PA0,那么我既可以把PAO这个通道放到任何一个没有使用的序列。其实这个序列个数就是对应的同时最多该序列个数的采集通道。例如ADC0,就包含16个通道,那么刚好对应的就是16个序列。

也就是在配置的时候我们必须将对应的通道配置某一个序列,不然无法完成有效采集数据。这是GD32F303的ADC配置要求。

单词转换,是每转换一次,需要触发源触发。可以理解为传感器1S采集一次数据,这个1S就是触发源。

转换完成以后会有一个EOC标志位,然后我们就根据这个标志位去除数据寄存器的数据,然后等待下一次触发源的到来

![[Pasted image 20250603184803.png]]

连续模式就不需要每次触发,只需要触发一次就行了。

转换完成以后会有一个EOC标志位,然后我们就根据这个标志位去除数据寄存器的数据,然后自动的进行下一次转换。

![[Pasted image 20250603184844.png]]

1.3.2 单次转换扫描转换

![[Pasted image 20250603184902.png]]

就是相当于是多个通道,但是都是在一个ADC,全部转换完成以后,才会产生一个标志位。这里就是前面说的,一个ADC完成多个引脚数据的采集,例如一个ADC组一个引脚采集1号位置电压、一个引脚采集二号位置电压等,可以简单这么理解。

单个通道转换完成以后会将数据放置AD数据寄存器里面,但是还不会产生EOC标志位, 必须要全部转换完成才能产生EOC标志位。

下一次转换,同样需要外部触发源触发。只要是单次,每转换一次都是需要一个触发源的,没有触发源我就不会采集转换。

存在的问题:

但是规则组只有一个数据寄存器,五个通道意味着,如果主流程来不及处理读取这个数据寄存器里面的数据,那么就会导致数据被覆盖掉,这样情况一定会存在的。

因此我们就需要用DMA进行处理,不需要经过CPU,不需要经过主循环。直接就从寄存器取走,然后存在数组中(也就是内存。)

这里就需要声明五个数组(因为五个通道,所以必须要五个数组),每个通道转换的结果,使用DMA立即取出,这样就不会出现覆盖,每一个通道的数据存放在对应的数组。

这里存在一个问题:就是我们怎么知道每一个通道完成了AD转换?

通道与通道转换的间隔理论上是触发DMA搬移数据的关键。
而EOC的标志位只是作为本次全部通道扫描完成的标志位,并且下一次开始也需要下一次触发源。

![[Pasted image 20250726194539.png]]

扫描模式就是只需要第一次给一个中断触发源,后续每一次都不需要触发源了,都是自动完成的。其他的道理是跟前面保持一致的。

1.4 ADC规则组和注入组

就像中断一样,中断可以打断主程序,那么注入组是可以打断规则组的转换。

![[Pasted image 20250603190339.png]]

注入组最多只能是四个序列,说白了这个地方个人理解是避免太多,导致嵌套太深图影响精度还容易爆炸。毕竟中断也不是无限的。

运行逻辑和中断打断主程序的流程是一样的,打断以后还必须恢复到规则组的被打断的地方。具体的实现一定要按照官方的Demo历程。

规则组:就是主循环

注入组:就是中断

一般注入组很少使用,基本上都是规则组就足够了。

官方Demo历程很关键,很重要!!!!!! 一定要参考,避免出现一些奇奇怪怪的Bug。

1.5 触发控制

以ADC0和ADC1为例:

在这里插入图片描述

可以通过定时器0设置不同的时间来开启触发源。

这个地方不同的芯片有不同的区别,并且这些是规定好的,必须要也只能这样用,个人理解是跟芯片内部封装实现有关。

外部中断也可以。

一般使用软件触发较多,配置寄存器里面的某一位,然后实现触发源,这个地方不是太理解。

ADC 外部触发源(ETSRC)的配置表,​软件触发(SWRCST)​​ 是指通过直接写寄存器的方式启动 ADC 转换的过程,无需依赖外部硬件信号(如定时器或 GPIO 中断)。

  • 当将 ADC 的触发源寄存器 ​**ETSRC[2:0] 设置为 111**​(对应SWRCST选项)时,ADC 的转换启动权完全交给软件控制。

  • 软件触发标志位​:当向 ADC 的 ​**SWRCST 位写入 1**​ 时,立即启动一次转换流程(类似"手动点火")。

  • 写入 SWRCST=1 后,ADC 内部逻辑:

    1️⃣ 清空当前转换状态(若有未完成转换则终止)

    2️⃣ 复位采样保持电路

    3️⃣ 开始采样指定通道电压

    4️⃣ 完成采样后启动 AD 转换

  • 转换完成后,​EOC(转换结束标志)被置位,可读取结果数据。

特性软件触发 (SWRCST)​硬件触发 (如 TIMER0)​
启动信号源写寄存器 SWRCST=1硬件事件(如定时器溢出、GPIO边沿)
精度控制由软件执行时机决定硬件精准同步(误差±10ns)
适用场景非周期/低频采样(如按键触发)高速/周期采样(如电机闭环控制)
CPU 参与度需主动触发自动触发(CPU仅需读数据)
  • 实时性约束​:

    • 软件触发不适合高精度定时场景​(如写寄存器到实际采样存在数十个时钟周期延迟)。

    • 若需严格定时采样,改用 ​TIMER 触发​(如配置 ETSRC[2:0]=000 由 TIMER0 驱动)。

  • 避免重复触发​:

    • 一次 SWRCST=1 仅启动 ​单次转换,若需连续转换需循环写入(或结合 DMA 连续传输)。

      典型应用场景
  1. 低功耗传感器轮询

    • 每 5 分钟唤醒 MCU,通过软件触发 ADC 读取温度传感器值。
  2. 事件驱动采集

    • 按键按下后触发 ADC 读取电池电压。
  3. 动态配置多通道

    • 循环切换 ADC 通道并触发转换(无需固定扫描序列)。


专栏介绍

嵌入式通信协议解析专栏
PID算法专栏
C语言指针专栏
单片机嵌入式软件相关知识
FreeRTOS源码理解专栏



文章源码获取方式:
如果您对本文的源码感兴趣,欢迎在评论区留下您的邮箱地址。我会在空闲时间整理相关代码,并通过邮件发送给您。由于个人时间有限,发送可能会有一定延迟,请您耐心等待。同时,建议您在评论时注明具体的需求或问题,以便我更好地为您提供针对性的帮助。

【版权声明】
本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议。这意味着您可以自由地共享(复制、分发)和改编(修改、转换)本文内容,但必须遵守以下条件:
署名:您必须注明原作者(即本文博主)的姓名,并提供指向原文的链接。
相同方式共享:如果您基于本文创作了新的内容,必须使用相同的 CC 4.0 BY-SA 协议进行发布。

感谢您的理解与支持!如果您有任何疑问或需要进一步协助,请随时在评论区留言。

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

相关文章:

  • Anaconda常用命令及环境管理指南
  • Redis的下载和安装(Linux)
  • 无源域自适应综合研究【3】
  • Java模块化编程深度指南:从过程式到面向对象的进化之路
  • vulhub Web Machine(N7)靶场攻略
  • 使用 Google Earth 的 DEM — 教程。
  • SpringMVC相关基础知识
  • selenium自动化鼠标和键盘操作
  • 【工程化】浅谈前端构建工具
  • 基于POD和DMD的压气机叶片瞬态流场分析与神经网络预测
  • 【GaussDB】如何从GaussDB发布包中提取出内核二进制文件
  • 嵌入式分享#27:原来GT911有两个I2C地址(全志T527)
  • 【Vue2】结合chrome与element-ui的网页端条码打印
  • matplotlib库 点线图,直方图,多子图与三维空间的可视化
  • 从0到1学Pandas(六):Pandas 与数据库交互
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-33,(知识点:二极管结温,热阻,二极管功耗计算)
  • golang实现一个规则引擎,功能包括实时增加、修改、删除规则
  • Jenkins持续集成工具
  • ACO-OFDM 的**频带利用率**(单位:bit/s/Hz)计算公式
  • Unity GenericMenu 类详解
  • 酒店智能门锁SDK新V门锁系统接口函数[2025版]Delphi 7.0——东方仙盟硬件接口库
  • 学习游戏制作记录(剑投掷技能)7.26
  • 中文语音识别与偏误检测系统开发
  • Java基础-文件操作
  • Spring boot Grafana优秀的监控模板
  • 生猪产业新生态:结构调整与种养结合,筑牢农业强国根基
  • HashMap(JDK1.7、JDK1.8)原理与结构分析与synchronizedMap()
  • 【LeetCode刷题指南】--队列实现栈,栈实现队列
  • C 语言详解:特性、应用与发展
  • GRE和MGRE综合实验