ADC电压采集(基于STM32hal库)(详细介绍)

目录

STM32 ADC电压采集

前言

ADC介绍

 STM32 ADC外设介绍

ADC主要特征

ADC系统框图

转换顺序

规则序列

注入序列

转换时间

ADC 时钟

采样时间

数据寄存器

规则数据寄存器

注入数据寄存器

ADC控制寄存器 2(ADC_CR2)

中断

转换结束中断

模拟看门狗中断

DMA 请求

电压转换

ADC 初始化结构体


STM32 ADC电压采集

前言

本文包括了模数转换器ADC的应用原理以及在STM32中ADC外设的介绍。

如果想要了解STM32中ADC外设的具体应用可参考:

ADC电压采集(基于STM32hal库)(保姆级应用)_竹烟淮雨的博客-CSDN博客

如果想要了解ADC在嵌入式实时操作系统RTOS中的应用,可参考:

RTT(RT-Thread)ADC设备(保姆级)_竹烟淮雨的博客-CSDN博客

ADC介绍

ADC电压采集(基于STM32hal库)(详细介绍)_第1张图片

这是一个典型的嵌入式闭环控制系统框图,在这个系统中将模拟量转化为数字量的过程称之为模数转换,而完成这一转换的器件叫做模数转换器(A/D转换器,简称ADC)。将数字量转换为模拟量的过程称之为数模转换,与之对应的器件叫做数模转换器(D/A转换器,简称DAC)。从图中我们可以看到只要和CPU(嵌入式控制系统)打交道的一定是数字量,而和被控制对象相关的一定是非电量(它可能是温度、也可能是某个电机的速度等等)。

模拟量与数字量之间的通信就需要使用AD转换与DA转换。

 ADC电压采集(基于STM32hal库)(详细介绍)_第2张图片

模拟信号的采集与处理过程如上图所示,就是传感器的信号通过运放进行放大,然后经过模拟开关采样,最后通过ADC转换成数字量给单片机的IO口,在微处理器进行数字信号的处理。

采集系统主要是由模拟信号的采集、AD转换、数字信号处理三个部分组成。

ADC电压采集(基于STM32hal库)(详细介绍)_第3张图片

ADC的原理:ADC转换主要包含两个内容,一是采样保持,再一个是量化编码成数字量给单片机去使用。

采用保持是指:单片机的ADC外设进行读取时,需要信号保持一会儿,才能完成量化编码的工作。图中所示ADC采样器将连续的模拟信号变成离散的信号,然后给单片机去使用,最后转换成数字量,这就是AD转换的核心。

量化编码分为多种算法,我们只需要知道STM32的ADC外设采用的是逐次比较型进行量化。

ADC电压采集(基于STM32hal库)(详细介绍)_第4张图片

STM32的ADC外设是传统的LPCM型ADC,我们在使用中主要关心的参数有以下五个

  • 分辨率:很多我们时候我们说一个N位的AD转换器它的分辨率就是N,一般的STM32 AD转换器至少支持到了12位。假设最大的输入电压是5V,那么它所能分辨的最小电压量为5/2^12。一个转换器的位数越多,那么它能够分辨的最小模拟电压值就越小。但ADC的测量结果是经过运算器放大的,传感器如果精度不够,往往得到的数据误差也会被放大,一个12bit的ADC,它可能只有前10位才是有效值,这就引出了第二个参数:相对精度
  • 相对精度:AD转换器实际输出数字量与理论值之间的最大的差值就称之为相对精度
  • 转换速度:AD转换器完成一次转换所需要的时间,STM32所使用的逐次比较型ADC外设一般是微妙级别的转换速度
  • 采样间隔时间(采样速率):不同于转换速率,采样速率也就是间隔转换时间,指的是两次转换的间隔时间。为了保证采样的正确完成,采样速率必须小于或者等于转换速率。可以说转换速率是最大的采样速率,因此我们习惯将转换速率在数值上设置等同于采样速率
  • 采样的电压范围:STM32一般为0-3.3V

一旦谈到AD采样,在大学教材里都会提到拉科斯特采样定理与香农定理,但就STM32外设的使用而言,我们不需要关心它,除非打算还原波形。

ADC电压采集(基于STM32hal库)(详细介绍)_第5张图片

 STM32 ADC外设介绍

以STM32F407ZGT6为例

它拥有3个分辨率为12bit,最大转换速率为2.4M,有24个通道,三个ADC交替采集同一个通道可以达到的最大转换速率为7.2M。其中SPS指的是转换速率,表示1S内完成模拟量转换为数字量的次数,所以单次转换时间为1/24000000

ADC电压采集(基于STM32hal库)(详细介绍)_第6张图片

我们STM32所有ADC的外设都是逐次比较型或者也叫逐渐逼近型。ADC转换器就速度划分有三种,一种为积分型ADC,它的转换时间是毫秒级,属于低速ADC;逐次比较型ADC的转换时间是微秒级;还有一些高速的专业ADC,采样并行或串并行,速度可以达到纳秒级。

逐次比较型:通俗理解,假如用一个天平来称量物品,但只有两个玛法,一个是128g,一个是64g;它称出来的重量肯定不准,所以如果再增加一个32g的砝码,称重就会更加精准一点;而我们继续添加16g、8g、4g、2g、1g的砝码,慢慢的可以测量的精度就增加了。因此逐次比较型与天平称重的原理类似:首先用大砝码,然后根据平衡的结果来决定是否留下这个大砝码或者换一个更小的砝码,不断重复步骤,按大小依次适用。

ADC主要特征

ADC电压采集(基于STM32hal库)(详细介绍)_第7张图片

我们以F1系列为例,其中需要解释的有:

  • 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
    • ADC有两种通道,一种是规则通道,一种是注入通道,转换的时候按通道设置的顺序依次进行转换。可能有些时候某些ADC通道不常使用,但是在某些情况下我们突然采集这些通道的电压的话,就需要使用注入通道。就相对于ADC在规则顺序采样的时候,我们突然来了一个插队。
    • 模拟看门狗的作用是我们设置一个阈值,比如当读取到的电压超过2.2v就产生一个中断事件
    • 溢出时间就是定时器中断,在电机驱动时会用到

ADC的采集有顺序,按规则通道分。但有些是不常采集或者过很多时间采集一次的可以放入注入通道,类似插队。

  • 从通道0到通道n的自动扫描模式
    • ADC设备在采集的时候,单次只能采集一个通道,如果有多个通道需要采集,我们需要设定采集的顺序。也支持多个ADC设备同时对同一个通道采集。

ADC电压采集(基于STM32hal库)(详细介绍)_第8张图片

    • 注意只有ADC1和ADC3支持DMA传输
    • 双ADC传输只能一起使用ADC1和ADC2,不能使用ADC3搭配其它ADC。使用时ADC1使用ADC_DR寄存器的低16位,ADC2使用高16位
    • 外部的 16 个通道在转换的时候又分为规则通道和注入通道,其中规则通道最多有 16 路,注入通 道最多有 4 路。
    • 温度传感器/ VREFINT内部通道 温度传感器和通道ADC1_IN16相连接,内部参照电压VREFINT和ADC1_IN17相连接。可以按注入 或规则通道对这两个内部通道进行转换。

注意: 温度传感器和VREFINT只能出现在主ADC1中。

  • 带内嵌数据一致性的数据对齐

ADC电压采集(基于STM32hal库)(详细介绍)_第9张图片

  • 采样间隔可以按通道分别编程
    • 采样时间就是两次转换之间的间隔,采样时间要确保小于等于转换时间
  • 间断模式
    • 间断模式就是不连续采样模式
  • 双重模式(带2个或以上ADC的器件)
    • 多个ADC设备同时对同一个通道采集
  • DMA请求

因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用 DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据。

只有在规则通道的转换结束时才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户 指定的目的地址。

注: 只有ADC1和ADC3拥有DMA功能。由ADC2转化的数据可以通过双ADC模式,利用ADC1的 DMA功能传输

  • 外部触发转换
    • 转换可以由外部事件触发(例如定时器捕获, EXTI线)。
  • ADC中断
    • 规则和注入组转换结束时能产生中断,当模拟看门狗状态位被设置时也能产生中断。它们都有 独立的中断使能位。

ADC系统框图

ADC电压采集(基于STM32hal库)(详细介绍)_第10张图片

  • ADC共有16个通道,其中规则通道16个,采集到的数据保存到规则数据寄存器中;注入通道4个,采集到的数据保存到注入数据寄存器中。
  • Vref、Vdda等四个脚用于设置ADC的电压输入范围,我们只需要看Vref+和Vref-即可

ADC电压采集(基于STM32hal库)(详细介绍)_第11张图片

  • ADC的时钟来源

ADC电压采集(基于STM32hal库)(详细介绍)_第12张图片

  • 模拟看门狗我们可以设置阈值上限和下限,用于产生看门狗中断事件
  • ADC可以搭配定时器使用,只支持通用定时器和高级定时器

转换顺序

规则序列

规则序列寄存器有 3 个,分别为 SQR3、 SQR2、 SQR1。 SQR3 控制着规则序列中的第一个到第六 个转换,对应的位为: SQ1[4:0]~SQ6[4:0],第一次转换的是位 4:0 SQ1[4:0],如果通道 16 想第一 次转换,那么在 SQ1[4:0] 写 16 即可。 SQR2 控制着规则序列中的第 7 到第 12 个转换,对应的位 为: SQ7[4:0]~SQ12[4:0],如果通道 1 想第 8 个转换,则 SQ8[4:0] 写 1 即可。 SQR1 控制着规则序 列中的第 13 到第 16 个转换,对应位为: SQ13[4:0]~SQ16[4:0],如果通道 6 想第 10 个转换,则 SQ10[4:0] 写 6 即可。具体使用多少个通道,由 SQR1 的位 L[3:0] 决定,最多 16 个通道。

ADC电压采集(基于STM32hal库)(详细介绍)_第13张图片

注入序列

注入序列寄存器 JSQR 只有一个,最多支持 4 个通道,具体多少个由 JSQR 的 JL[2:0] 决定。如果 JL 的值小于 4 的话,则 JSQR 跟 SQR 决定转换顺序的设置不一样,第一次转换的不是 JSQR1[4:0], 而是 JCQRx[4:0] , x = (4-JL),跟 SQR 刚好相反。如果 JL=00(1 个转换),那么转换的顺序是 从 JSQR4[4:0] 开始,而不是从 JSQR1[4:0] 开始,这个要注意,编程的时候不要搞错。当 JL 等于 4 时,跟 SQR 一样。

ADC电压采集(基于STM32hal库)(详细介绍)_第14张图片

转换时间

ADC 时钟

ADC 输入时钟 ADC_CLK 由 PCLK2 经过分频产生,最大是 14M,分频因子由 RCC 时钟配置寄 存器 RCC_CFGR 的位 15:14 ADCPRE[1:0] 设置,可以是 2/4/6/8 分频,注意这里没有 1 分频。一 般我们设置 PCLK2=HCLK=72M。

采样时间

ADC 使用若干个 ADC_CLK 周期对输入的电压进行采样,采样的周期数可通过 ADC 采样时间 寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMP[2:0] 位设置, ADC_SMPR2 控制的是通道 0~9, ADC_SMPR1 控制的是通道 10~17。每个通道可以分别用不同的时间采样。其中采样周期最小是 1.5 个,即如果我们要达到最快的采样,那么应该设置采样周期为 1.5 个周期,这里说的周期就 是 1/ADC_CLK。

ADC 的转换时间跟 ADC 的输入时钟和采样时间有关,公式为: Tconv = 采样时间 + 12.5 个周期。 当 ADCLK = 14MHZ(最高),采样时间设置为 1.5 周期(最快),那么总的转换时间(最短) Tconv = 1.5 周期 + 12.5 周期 = 14 周期 = 1us。

一般我们设置 PCLK2=72M,经过 ADC 预分频器能分频到最大的时钟只能是 12M,采样周期设 置为 1.5 个周期,算出最短的转换时间为 1.17us,这个才是最常用的。

数据寄存器

一切准备就绪后, ADC 转换后的数据根据转换组的不同,规则组的数据放在 ADC_DR 寄存器, 注入组的数据放在 JDRx

规则数据寄存器

ADC 规则组数据寄存器 ADC_DR 只有一个,是一个 32 位的 寄存器,低 16 位在单 ADC 时使用, 高 16 位是在 ADC1 中双模式下保存 ADC2 转换的规则数据,双模式就是 ADC1 和 ADC2 同时使 用。在单模式下, ADC1/2/3 都不使用高 16 位。因为 ADC 的精度是 12 位,无论 ADC_DR 的高 16 或者低 16 位都放不满,只能左对齐或者右对齐,具体是以哪一种方式存放,由 ADC_CR2 的 11 位 ALIGN 设置。

规则通道可以有 16 个这么多,可规则数据寄存器只有一个,如果使用多通道转换,那转换的数 据就全部都挤在了 DR 里面,前一个时间点转换的通道数据,就会被下一个时间点的另外一个通 道转换的数据覆盖掉,所以当通道转换完成后就应该把数据取走,或者开启 DMA 模式,把数据 传输到内存里面,不然就会造成数据的覆盖。最常用的做法就是开启 DMA 传输。

ADC电压采集(基于STM32hal库)(详细介绍)_第15张图片

注入数据寄存器

ADC 注入组最多有 4 个通道,刚好注入数据寄存器也有 4 个,每个通道对应着自己的寄存器,不 会跟规则寄存器那样产生数据覆盖的问题。 ADC_JDRx 是 32 位的,低 16 位有效,高 16 位保留, 数据同样分为左对齐和右对齐,具体是以哪一种方式存放,由 ADC_CR2 的 11 位 ALIGN 设置。

ADC电压采集(基于STM32hal库)(详细介绍)_第16张图片

ADC控制寄存器 2(ADC_CR2)

ADC电压采集(基于STM32hal库)(详细介绍)_第17张图片

中断

转换结束中断

        数据转换结束后,可以产生中断,中断分为三种:规则通道转换结束中断,注入转换通道转换结 束中断,模拟看门狗中断。其中转换结束中断很好理解,跟我们平时接触的中断一样,有相应的 中断标志位和中断使能位,我们还可以根据中断类型写相应配套的中断服务程序。

模拟看门狗中断

        当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断,前提是我们开启了模 拟看门狗中断,其中低阈值和高阈值由 ADC_LTR 和 ADC_HTR 设置。例如我们设置高阈值是 2.5V,那么模拟电压超过 2.5V 的时候,就会产生模拟看门狗中断,反之低阈值也一样。

DMA 请求

规则和注入通道转换结束后,除了产生中断外,还可以产生 DMA 请求,把转换好的数据直接存 储在内存里面。要注意的是只有 ADC1 和 ADC3 可以产生 DMA 请求。

因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用 DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据。

只有在规则通道的转换结束时才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户 指定的目的地址。

电压转换

        模拟电压经过 ADC 转换后,是一个 12 位的数字值,如果通过串口以 16 进制打印出来的话,可 读性比较差,那么有时候我们就需要把数字电压转换成模拟电压,也可以跟实际的模拟电压(用 万用表测)对比,看看转换是否准确。

        我们一般在设计原理图的时候会把 ADC 的输入电压范围设定在: 0~3.3v,因为 ADC 是 12 位的, 那么 12 位满量程对应的就是 3.3V, 12 位满量程对应的数字值是: 2^12。数值 0 对应的就是 0V。 如果转换后的数值为 X , X 对应的模拟电压为 Y,那么会有这么一个等式成立:

2^12 / 3.3 = X / Y, => Y = (3.3 * X ) / 2^12。

ADC 初始化结构体

HAL 库函数对每个外设都建立了一个初始化结构体 xxx_InitTypeDef(xxx 为外设名称),结构体成 员用于设置外设工作参数,并由 HAL 库函数 xxx_Init() 调用这些设定参数进入设置外设相应的 寄存器,达到配置外设工作环境的目的。

结构体 xxx_InitTypeDef 和库函数 xxx_Init 配合使用是 HAL 库精髓所在,理解了结构体 xxx_InitTypeDef 每个成员意义基本上就可以对该外设运用自如了。结构体 xxx_InitTypeDef 定义stm32f1xx_hal_xxx.h 文件中,库函数 xxx_Init 定义在 stm32f1xx_hal_xxx.c 文件中,编程时我们 可以结合这两个文件内注释使用。

ADC_InitTypeDef 结构体定义在 stm32f1xx_hal_adc.h 文件内,具体定义如下:

ADC电压采集(基于STM32hal库)(详细介绍)_第18张图片

  • Mode:配置 ADC 的模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模 式下还有很多细分模式可选,具体配置 ADC_CR1:DUALMOD 位。
  • ScanConvMode:可选参数为 ENABLE 和 DISABLE,配置是否使用扫描。如果是单通道 AD 转换 使用 DISABLE,如果是多通道 AD 转换使用 ENABLE,具体配置 ADC_CR1:SCAN 位。
  • ContinuousConvMode:可选参数为 ENABLE 和 DISABLE,配置是启动自动连续转换还是单次转 换。使用 ENABLE 配置为使能自动连续转换;使用 DISABLE 配置为单次转换,转换一次后停止 需要手动控制才重新启动转换,具体配置 ADC_CR2:CON 位。
  • ExternalTrigConv:外部触发选择,图 29‑1 中列举了很多外部触发条件,可根据项目需求配置触 发来源。实际上,我们一般使用软件自动触发。
  • DataAlign: 转换结果数据对齐模 式, 可选右对齐ADC_DataAlign_Right 或 者 左 对 齐 ADC_DataAlign_Left。一般我们选择右对齐模式。
  • NbrOfChannel: AD 转换通道数目,根据实际设置即可。具体的通道数和通道的转换顺序是配置规则序列或注入序列寄存器。

你可能感兴趣的:(stm32,嵌入式硬件,单片机,ADC)