发新帖本帖赏金 70.00元(功能说明)我要提问
返回列表
[MM32生态]

ADC 外设相关的知识点小结

[复制链接]
813|14
手机看帖
扫描二维码
随时随地手机跟帖
yang377156216|  楼主 | 2022-7-6 19:03 | 显示全部楼层 |阅读模式
本帖最后由 yang377156216 于 2022-7-6 19:36 编辑
#申请原创#  @21小跑堂

     本文主要目的在于记录使用灵动微 MM32F0144C6P 芯片过程中遇到的 ADC 相关的问题以及知识点,主要参考官方 UM 手册、DS 手册以及库例程。这颗芯片的官方资料链接为: https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f_value_line/mm32f0140/ ,基础资源都已经涵盖。本文涉及内容可以分为以下几个章节:
  • ADC 功能模块框图
  • ADC 模块特性及参数指标
  • ADC 功能描述和寄存器
  • ADC 硬件抽象层驱动库函数
  • ADC 采样电路

一、功能模块框图
通过查看芯片的数据手册可以知道, MM32F0144C6P 这颗 MCU 内嵌了 1 个 12 位 SAR 型 ADC,并且具有 13 个外部输入通道和 2 个内部通道(包括了一个温度传感器和一个 BandGap 参考基准电压)。既然为逐次逼近型的模/数转换器,那它内部的电路结构应该与下图类似了:
12 位 SAR ADC 电路结构.png
SAR ADC 通常是 8 位到 18 位的中等分辨率应用的首选,一般可以在高达几兆赫兹的最大采样率下运行。通过上面结构图可以看出,这种模拟转换器分为 2 个部分,前端通过采样保持电路元器件去捕获住接入的模拟电压信号,然后进入到后端,将此输入的信号电压由转换器根据外部或者内部的参考电压逐一进行比较,一般使用的是电容式 DAC 网络来做这个连续逐次比较工作的,最后将比较得出的数据结果放置于 data register 中即完成了一次采样转换工作。具体的逐次比较涉及内容比较深,在此不做过多探讨了,我根据理解将该结构转化了一个示意说明图如下,一般的电路结构应该都是这么设计的:
SAR ADC 电路结构.jpg
上面为 SAR ADC 普遍的结构,针对具体芯片的 ADC 功能框图可以在用户手册的 ADC 章节中找到,如下:
MM32F0140 ADC 功能框图.png
从图中得知,该 ADC 模块数字组成部分有:时钟源、外部通道IO、内部温度传感器以及基准电压器件、参考电源电压、各个工作模式配置以及触发源配置等相关寄存器、转换结果及状态寄存器等等。温度传感器通道在 ADC 的 AIN14 通道,内部参考电压通道在 AIN15 通道上。

二、ADC 模块特性及参数指标
在用户手册的 ADC 章节中有主要特性描述,我将内容提炼整理成大白话了,该模块主要有以下一些特性:
ADC 主要特性.png
这是一个 12 位逐次逼近型(SAR)模拟/数字转换器 (ADC),最高支持 12 位可编程分辨率,一般实际能到 10 - 11.5 位就已经很不错了,可以通过转换后的数值评估;
有 13 路外部输入通道和 2 路内部通道,用户手册上写的是 14 路外部通道而数据手册上只开放了 13 路,应该以具体型号的数据手册为准吧;
ADC 的工作时钟由 PCLK2 分频产生,最大输入时钟为 16MHz,此时钟源提供了采样保持和转换相关的工作时序,输入时钟要是超过了 16MHz 应该会导致内部时序的紊乱吧;
支持最高为 1Msps 的转换速率,这个转换速率指的是每个通道完成采样保持到转换后得到实际数据这一系列工作的频率,如果频繁地转换以至于超过了这个速率那应该会得到不准确的数据;
支持普通通道、任意通道和注入通道 3 种不同工作序列,前 2 者包含了 单次转换、单周期扫描以及连续扫描方式,注入模式只支持自动注入方式且带数据补偿配置,其中的普通通道序列也就是从 AIN0 到 AIN12(或者反向)这样的规则组模式,任意通道序列就是将 N 个任意通道号放到一个序列里面,而注入序列只能是紧跟着任意通道序列的,当前面任意通道序列转换完成后自动进行注入组的转换;
每个通道的采样保持时间可以通过软件按通道分别配置,最小为 2.5 个 ADC 时钟周期,这个保持时间需要尤其关注哟,它直接影响了采样保持电路中的电容充放电时间,如果配置不好小了或者大了都会影响到实际转换的数据精度,且内部通道一般受设计影响都需要将保持时间放到最大;
A/D 转换的数据可以使用轮询或者中断方式从相关数据寄存器中获取,普通通道序列以及任意通道序列中的通道还可支持 DMA 传输,在需要高速转换应用中一般都会使用 DMA 传输,通过查看 DMA 章节得知,ADC 可以被映射在 DMA_CH1 和 DMA_CH2 两个通道上,根据 SYSCFG_CFGR 寄存器配置去做切换;
A/D 转换开始的触发条件有软件开关触发、外部中断线信号触发以及 TIM 匹配或更新事件等,不同应用需要配置不同的触发条件,比如说 BLDC FOC 中一般都会应用到 TIM 的 CC4/CC5 去做触发采样;
具有模拟看门狗功能,可以设置参与比较的指定通道、比较的上下限值,指定通道转换得到的结果可和指定的阈值区间相比较,从而达到时刻监测被测通道的电压值效果,并且还可以产生相应中断,这个功能就类似模拟比较器。
以上是整体特性描述,再来看数据手册中关于 ADC 的一些参数指标:
ADC 参数1.png ADC 参数2.png ADC 参数3.png ADC 参数4.png
根据这些数据表,可以知道参考电压来自电源脚 VDDA 和 VSSA ,且内部 VSSA 与 VSS 是连接在一起的,如果将 VDDA 与 VDD 分开供电,那么 VDDA 不能超过 VDD 电压且压差保持在 100mV 以内。有效分辨率位数达到 10.7 位,在工程值可接受范围内。需要避免在任何标准的模拟输入引脚上注入反向电 流,因为这样会显著地降低另一个模拟输入引脚上正在进行的转换精度。可在可能产生反向注入电流的标准模拟引脚上(引脚与地之间)增加一个肖特基二极管。静态线性误差几乎都在 8 个 LSB 以内,精度比较高。

三、功能描述和寄存器
1. 中断
当配置中断使能后,中断事件发生后将产生相应的中断请求,不同工作序列和工作模式中涉及到不同的中断标志,具体有以下状态标志位:
ADC 中断.png
每个状态标志位都会在相应事件发生后置位,同时发出中断请求给到 CPU ,如果正确配置并且开启 ADC 的 NVIC 通道那么就会产生中断响应,然后在响应服务函数中根据不同的标志位置位情况分别进行处理。这些标志位中,标注为 rc_w1 的表示可以写 “1” 清除。

2. DMA 响应
A/D 转换结果存储在数据寄存器 ADC_ADDATA 中,当多个通道连续转换时可以使用 DMA 访问保存数据,避免转换数据丢失,当然一个通道转换也是可以用 DMA的 ;
DMA 使能开启后,当通道转换结束后将产生 DMA 请求,将转换数据从 ADC_ADDATA 寄存器传输到软件指定的目的地址;
每个通道有对应的数据寄存器 ADC_ADDRn,可访问这些寄存器获取各通道转换结果,当然也可以将 ADC DMA 通道的源地址设置为 ADC_ADDRn ;
ADC DMA 通道重映射(ADC DMA remap) 在 SYSCFG_CFGR Bit 8 中配置
  • 0:ADC 的 DMA 功能映射到 DMA channel1
  • 1:ADC 的 DMA 功能重映射到 DMA channel2

3. 时钟、分频、分辨率以及采样转换时间

输入时钟与 APB2_CLK 同步,在使用 ADC 之前,需要先使能 RCC 控制器中的时钟使能控制位(RCC_APB2ENR 的 Bit 9);
ADC 预分频相关寄存器为 ADC_ADCFG 的 ADCPREH 和 ADCPREL,分频值为 (ADC_ADCFG [bit6~4,bit14]+2) ,分频后作为 ADC 工作时钟;
ADC 转换分辨率可通过 ADC_ADCFG.RSLTCTL[2:0] 位配置,有效数据位默认是 12 位数据右对齐,也可以配成左对齐, 通过配置低分辨率可加快数据转换速率;
采样转换频率计算公式 : Fsample = Fadc_clk /(m+n+0.5) ,Fadc_clk 为 ADC 的工作时钟频率,m 为每个通道采样保持周期,不同通道可以有不同的采样保持周期,n 为分辨率,二者皆可通过相关寄存器改变配置。另外可通过该公式计算每个通道转换一次需要的时间 : Tconv = (m+n+0.5) clk,取 n=12 bit,m = 3.5 clk ,Fadc_clk = 16 MHz ,则 1 clk = 1/16 us ,该通道转换一次的时间为 1/16 us * 16 = 1us 。


4. 采样方式以及通道序列模式
单次采样方式,只对一个指定通道进行 A/D 转换,此时一个通道也称之为一个普通序列,对应 ST 的就是不使能连续模式且通道数为 1;
单周期扫描采样方式,将使能的通道按顺序(方向可正反改变)进行一次 A/D 转换,对应 ST 的就是不使能连续模式且通道数为 N;
连续扫描采样方式,循环单周期扫描采样的转换动作,对应 ST 的就是使能连续模式且通道数为 N;
普通规则通道序列,一个通道也可以自己组成一个序列;
任意通道序列,可以是同一个通道多次放置于一个任意序列中;
注入通道序列,前 2 种序列模式包含上述 3 种采样方式,而注入序列模式只包含自动注入,且只能与任意通道工作模式搭配工作。
下面是用户手册中描述的一些转换时序图,对于理解该模块工作的具体逻辑实现非常有帮助,里面告诉了我们在每个 ADC 时钟 clk 驱动下,什么时候开始采样,转换后的结果在什么时候被 DMA 搬运走,每个通道完成转换后 ADC 相关的标志位置位的具体时刻,等等一些有用信息:
ADC 单周期时序图.png

5. 通道选择和触发源选择
ADC 有 13 路外部输入通道 0~12、内部温度传感器通道 14 和内部 1.2V 参考电压通道 15;
可根据对应工作模式去配置通道选择寄存器从而进行不同方式的 A/D 转换,正常转换过程中也是可以进行切换通道的,只是不同模式下对切换通道的响应是不同的,这里就牵扯到一个影子寄存器的说法了,具体可以通过用户手册中查看详细描述;
ADC 触发源可以是软件开关位,也还包括了定时器和外部事件,具体罗列在以下表中,不同源头的选择需要在初始化时进行不同配置,除软件触发外都需要额外开启外部触发位。
ADC 触发源.png

6. 数据获取方式以及数据寄存器
可以通过以下几种方式进行转换结果的数据获取:
  • 轮询,开启转换后等待转换完成标志位置位
  • 中断,使能转换完成中断标志并且开启转换后等待自动触发中断
  • DMA,使能对应 A/D 通道并且开启转换后等待每个通道转换完成后发出的 DMA 请求,转换数据自动搬运到 RAM 中
A/D 转换完成后,非注入通道转换结果存储在寄存器 ADC_ADDATA 中,CHANNELSEL 表示当前数据对应的非注入通道号,同步地还会单独保存在对应的ADC_ADDR0~15 通道数据寄存器中;
注入通道转换结果存储在寄存器 ADC_JADDATA 中,JCHANNELSEL 表示当前数据对应的注入通道号,同步地还会单独保存在对应的 ADC_JDR0~3  注入通道数据寄存器中。

7. 数据对齐及补偿
通过配置 ADC_ADCR 寄存器中的 ALIGN 位,可以选择转换后数据储存为左对齐或右对齐;
非注入通道数据没有数据补偿,而注入通道道 转换数据带有数据补偿(ADC_JOFR0~3),因此它的结果可以是负值,SEXT 位是扩展的符号值(1 代表负数 ,0 代表正数)
ADC 数据补偿.png

8. 内部通道
根据用户手册上的说明可知,内置的温度传感器仅用于检测器件内部的温度变化(TA),精度范围在正负 10 度以内,所以一般要求比较高的应用就还是用 NTC 等外部温传更为合理;
在得到正确的温度传感器通道数值后,通过以下公式进行计算温度工程值,它是根据出厂前校准的 25 度温度对应的通道数值反推的:
ADC 温度传感器计算公式.png
同样地,内部 1.2 V BandGap 参考电压在出厂前也被校准了,原厂将对应的校准 A/D 数值保存在内部 flash 中,通常可以通过此数据去反推当前 VDDA 电源电压值,如果认为板级的模拟电源 VDDA 电压较为精准且稳定,那么就可以去计算出实际的 1.2 V 参考电压到底为多少了,具体可以根据下面 2 个公式进行正算和反推:
ADC 内部参考电压.png

9. 寄存器表
ADC 寄存器描述.png

四、ADC 硬件抽象层驱动库函数
通过官方下载到库例程,ADC 模块硬件抽象层涉及到以下几个文档:
reg_adc.h   
     主要描述 ADC 模块在 MCU 中所处的存储地址以及寄存器和对应位的内容定义和偏移
hal_adc.h
     主要声明 ADC 模块硬件抽象层驱动库接口 API 函数以及寄存器操作用到的数据类型定义
hal_adc.c
     主要实现 ADC 模块硬件抽象层驱动库接口 API 函数
主要抽象出的接口函数如下,包括了初始化和反初始化、模块使能与禁止、标志位的获取和清除、中断的开启与禁止、通道的配置、内部通道开启与禁止、获取 ADC 转换数据、ADC DMA 开启与禁止、外部触发使能与禁止、任意通道的配置、注入通道的配置等等:
ADC API 函数.png

简单说明 ADC 模块软件配置流程如下:
  • ADC 对应通道的 IO 模式首先配置为模拟输入 ;
  • 开启 ADC 在 RCC 中的时钟位 ;
  • 初始化 ADC_InitStruct ,其中包含时钟分频数、分辨率、采样方式及模式、对齐方式、触发源选择、触发边沿、触发延时、采样保持周期等 ;
  • 开启 ADC 模块 ;
  • 根据不同的触发转换方式去触发 A/D 转换 ;
  • 根据不同的获取数据方式判断标志位、清标志位以及读取数据寄存器,得到相应转换结果 。

五、ADC 采样电路
先根据数据手册清楚每个采样通道是如何对应到 IO 上的:
ADC 通道 IO.png
再根据手册中的阻抗匹配公式去做好采样匹配电路的设计:
ADC 采样电路.png
一般情况下,不关心驱动能力和功耗的话,都采用经典的分压电路+RC 滤波匹配以及并上防倒灌的反向二极管即可,如上面的右上方,计算出 Rain = 8.6k + 2k ,采样保持时间可以选用 29.5 cycles (ADC 时钟为 15M 时),分压电阻最好同步调节到 几k 至 几十k 范围内,因为如果到 M 级别的话势必会增大外部输入阻抗导致不能有太快的采样率。另外,如果需要更高的采样精度、更低的功耗、更强的驱动能力,那采样电路在设计上最好加上一个低功耗的放大器作为一级跟随,用于阻抗匹配。不管哪种设计,都需要保证 VDDA 的精度要高且稳定,而且输入到 IO 内部的电压不能超过 VDDA 值。以下为加入运放的设计结构示意:
ADC 由运放驱动.png
在实际工程应用中,遇到过一些问题:
1. 有时候改变普通通道序列的正方向顺序,会改善转换结果,这点没有分析和找出根本原因所在 ;
2. 在每次采样转换过程中,通道上引入的电压值波形会出现阶梯式地递减,在完成转换工作后恢复到原始值,这点不清楚是否符合设计原理 ;
3. 用软件触发,ADC 循环模式工作并且触发 DMA 一直搬运数据,这种情况会有概率发生数据错序的问题,改用 TIM 触发 ADC 单周期采样然后进行 DMA 搬运。
希望走过路过的朋友们一起来探讨一下呀 作为回馈,我将自己私藏的宝贝《如何在STM32微控制器中获得最佳ADC精度》中英文版资料分享给大家,希望能帮助大伙儿能够发挥出 MCU 内部 ADC 的最佳性能。
ADC 实测波形.png

如何在STM32微控制器中获得最佳ADC精度.zip (1.59 MB)

使用特权

评论回复

打赏榜单

21小跑堂 打赏了 70.00 元 2022-07-08
理由:恭喜通过原创文章审核!请多多加油哦!

评论
21小跑堂 2022-7-8 10:30 回复TA
从MM32F0144切入,简述了ADC的相关原理和使用技巧,文章层次分明,结构合理,对ADC外设有自我理解。 整理了较多网络资料,摘出部分内容,但是整体质量尚可。内容因为引用了官方资料,导致过于书面化,可读性有待加强哦~ 
daichaodai| | 2022-7-7 08:13 | 显示全部楼层
学习了,谢谢楼主分享经验。

使用特权

评论回复
麻花油条| | 2022-7-7 15:06 | 显示全部楼层
图文并茂,讲解真详细

使用特权

评论回复
onlycook| | 2022-7-14 14:58 | 显示全部楼层
感谢分享,学习了

使用特权

评论回复
laocuo1142| | 2022-7-18 10:27 | 显示全部楼层
ADC是很重要的功能,学习了

使用特权

评论回复
tpgf| | 2022-8-1 15:31 | 显示全部楼层
主要是这个电阻匹配不好弄啊

使用特权

评论回复
qcliu| | 2022-8-1 15:38 | 显示全部楼层
感觉切入点非常不错

使用特权

评论回复
drer| | 2022-8-1 15:51 | 显示全部楼层
adc玩精了可不容易

使用特权

评论回复
coshi| | 2022-8-1 16:02 | 显示全部楼层
adc采样电路都需要关注哪些点呢

使用特权

评论回复
kxsi| | 2022-8-1 16:26 | 显示全部楼层
不同模式适用于什么场合呢

使用特权

评论回复
wiba| | 2022-8-1 16:41 | 显示全部楼层
波形效果真是非常的理想啊

使用特权

评论回复
match007| | 2022-8-9 21:16 | 显示全部楼层
不错,学习中~

使用特权

评论回复
cyclefly| | 2022-8-13 13:59 | 显示全部楼层
真心不错啊

使用特权

评论回复
内政奇才| | 2022-8-16 15:27 | 显示全部楼层
波形效果真的很不错了

使用特权

评论回复
发新帖 本帖赏金 70.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

162

帖子

10

粉丝