单片机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硬件了解
言归正传:
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。
以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关系
通过该图就可以看出来,芯片不同的引脚对应不同的ADC组别,与上面介绍的ADC0、ADC1、ADC2互相印证。可以看出不同的组别包含的GPIO端口是不一样的,但是有些部分是共用的,在啰嗦一句,该芯片也只能使用使用这些GPIO作为ADC转换,其他的端口你就是想用也用不了,这是因为芯片内部的是没有硬件电路支持的。
其实这里有一个疑问:就是为什么相同的一个GPIO会被分到不同的组别,这样做有什么意义吗?
1.2.1 信号冗余与系统可靠性提升
-
故障容错机制
-
若某一ADC模块(如ADC0)因干扰或硬件故障失效,其他ADC(如ADC1/2)可继续采集同一信号源的数据(例如PA0引脚的电压),确保关键数据不丢失。
-
应用场景:工业控制、医疗设备等对稳定性要求极高的系统。
-
1.2.2 多维度同步采样与分析
-
同步测量需求
-
严格时对齐采样:多个ADC可通过硬件触发同时采集同一GPIO信号,消除时间漂移误差。
-
应用实例:
-
电机控制中三相电流的瞬时同步采样,计算功率因数和谐波分量。
-
音频系统的多声道同步采集,避免相位失真。
-
-
-
差异化采样配置
-
不同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进行同步转换,并用两个数组分别存储结果。
-
冗余备份系统
- 航天设备中同时用ADC0/ADC1采集同一传感器数据,投票机制提升可靠性。
-
差分噪声分析
- 对比两个ADC结果差值,分离系统噪声(如电源纹波)与信号真实波动。
-
同步多速率采样
- ADC0低速采样监测长期趋势,ADC1高速捕捉瞬态脉冲(如电源故障检测)。
1.3 ADC转换模式
单次模式:的意思是每次转换,都需要外部触发,也就是给一个信号。
连续模式:就是在最开始的时候给出一个外部触发信号,后续就自动完成触发。
扫描模式:如果是多个通道,肯能就需要扫描模式,这样每个都能采集到。一个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标志位,然后我们就根据这个标志位去除数据寄存器的数据,然后等待下一次触发源的到来。
连续模式就不需要每次触发,只需要触发一次就行了。
转换完成以后会有一个EOC标志位,然后我们就根据这个标志位去除数据寄存器的数据,然后自动的进行下一次转换。
1.3.2 单次转换扫描转换
就是相当于是多个通道,但是都是在一个ADC,全部转换完成以后,才会产生一个标志位。这里就是前面说的,一个ADC完成多个引脚数据的采集,例如一个ADC组一个引脚采集1号位置电压、一个引脚采集二号位置电压等,可以简单这么理解。
单个通道转换完成以后会将数据放置AD数据寄存器里面,但是还不会产生EOC标志位, 必须要全部转换完成才能产生EOC标志位。
下一次转换,同样需要外部触发源触发。只要是单次,每转换一次都是需要一个触发源的,没有触发源我就不会采集转换。
存在的问题:
但是规则组只有一个数据寄存器,五个通道意味着,如果主流程来不及处理读取这个数据寄存器里面的数据,那么就会导致数据被覆盖掉,这样情况一定会存在的。
因此我们就需要用DMA进行处理,不需要经过CPU,不需要经过主循环。直接就从寄存器取走,然后存在数组中(也就是内存。)
这里就需要声明五个数组(因为五个通道,所以必须要五个数组),每个通道转换的结果,使用DMA立即取出,这样就不会出现覆盖,每一个通道的数据存放在对应的数组。
这里存在一个问题:就是我们怎么知道每一个通道完成了AD转换?
通道与通道转换的间隔理论上是触发DMA搬移数据的关键。
而EOC的标志位只是作为本次全部通道扫描完成的标志位,并且下一次开始也需要下一次触发源。
扫描模式就是只需要第一次给一个中断触发源,后续每一次都不需要触发源了,都是自动完成的。其他的道理是跟前面保持一致的。
1.4 ADC规则组和注入组
就像中断一样,中断可以打断主程序,那么注入组是可以打断规则组的转换。
注入组最多只能是四个序列,说白了这个地方个人理解是避免太多,导致嵌套太深图影响精度还容易爆炸。毕竟中断也不是无限的。
运行逻辑和中断打断主程序的流程是一样的,打断以后还必须恢复到规则组的被打断的地方。具体的实现一定要按照官方的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 连续传输)。
典型应用场景:
- 一次
-
低功耗传感器轮询
- 每 5 分钟唤醒 MCU,通过软件触发 ADC 读取温度传感器值。
-
事件驱动采集
- 按键按下后触发 ADC 读取电池电压。
-
动态配置多通道
- 循环切换 ADC 通道并触发转换(无需固定扫描序列)。
专栏介绍
嵌入式通信协议解析专栏
PID算法专栏
C语言指针专栏
单片机嵌入式软件相关知识
FreeRTOS源码理解专栏
文章源码获取方式:
如果您对本文的源码感兴趣,欢迎在评论区留下您的邮箱地址。我会在空闲时间整理相关代码,并通过邮件发送给您。由于个人时间有限,发送可能会有一定延迟,请您耐心等待。同时,建议您在评论时注明具体的需求或问题,以便我更好地为您提供针对性的帮助。
【版权声明】
本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议。这意味着您可以自由地共享(复制、分发)和改编(修改、转换)本文内容,但必须遵守以下条件:
署名:您必须注明原作者(即本文博主)的姓名,并提供指向原文的链接。
相同方式共享:如果您基于本文创作了新的内容,必须使用相同的 CC 4.0 BY-SA 协议进行发布。
感谢您的理解与支持!如果您有任何疑问或需要进一步协助,请随时在评论区留言。