嵌入式系统(八):ADC原理及应用

一、ADC概述

1:概述

  • 模数(A/D)转换: 将模拟量转换为数字量的过程
  • 模数转换器 完成这一转换的器件称为模数转换器(简称ADC)
  • 数模(D/A)转换 将数字量转化为模拟量的过程
  • 数模转换器 完成这一转换的器件称为数模转换器(简称DAC)

A/D转换中通常要经过以下两步:

  • 采样保持:A/D转换需要时间,一般在us级别
  • 量化编码:将采样后得到的样点幅值转换为数字量(是模数转换的核心。以一定的量化单位,将信号的连续取值近似为有限的离散值的过程。)
    常见技术:
    计数式、双积分转换
    逐次逼近式转换
    并联式转换
  • 采样保持只是保证信号一段时间内不变,量化编码才是转化中最重要的部分。

  • STM32在片上集成的ADC外设非常强大,12位ADC是一种逐次逼近型模数转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次连续扫描间断模式执行。
  • ADC的转换结果是12位,最后存储在16位的寄存器中:(这些都是需要自己初始化的)
    左对齐:12位的最高位是寄存器的最高位,低四位没有数据
    右对齐:12位的最低位是寄存器的最低位,高四位没数据
  • 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

2:STM32的ADC功能及结构

  • STM32F103RB系列产品内嵌212位的模拟/数字转换器(ADC),每个ADC共用多达16个外部通道,可以实现单次或扫描转换。
  • ADC的分辨率为12位;供电为2.4~3.6V;输入范围为0~3.6V(VREF-≤VIN≤VREF+);转换时间是可编程的,采样一次至少要用14个ADC时钟周期,而ADC的时钟频率最高为14MHz,也就是说它的采样时间最短为1us,足以胜任中、低频数字示波器的采样工作。

(1)具体功能

1)规则转换注入转换均有外部触发选型;

2)在规则通道转换期间,可以产生DMA(直接存储器存取)请求;(由于转化后的12位数据一般存储在ADC的寄存器中,转化后可以直接用DMA直接存储到存储器中),注入转换不允许产生DMA请求。

3)自校准,在每次ADC开始转换前进行一次自校准

4)通道采样间隔时间:可编程;

5)带内嵌数据一致性的数据对齐;(12位存储到16位的寄存器,我们需要设置左对齐还是右对齐)

6)可设置成单次、连续、扫描、间断模式;

7)双ADC模式,带2个ADC设备ADC1和ADC2;

8)规则转换结束、注入转换结束和发生模拟看门狗事件(输入电压超出阈值)时产生中断

(2)硬件结构

  • 1)模拟信号通道。 共有18个通道(可以看作输入的引脚,可以检测的源),可测16个外部信号源2个内部信号源。其中16个外部通道对应ADCx_IN0到ADCx_IN15;2个内部通道连接到温度传感器和内部参考电压( V R E F I N T = 1.2 V V_{REFINT}=1.2V )。
  • 2)A/D转换器。转换原理为逐次逼近型A/D转换,分为注入通道规则通道。每个通道都有相应的触发电路,注入通道的触发电路为注入组,规则通道的触发电路为规则组;每个通道也有相应的转换结果寄存器,分别称为规则通道数据寄存器和注入通道数据寄存器。
  • 3)模拟看门狗部分。用于监控高低电压阈值,可作用于一个、多个或全部转换通道,当检测到的电压低于或高于设定电压阈值时,可以产生中断。
  • 4)中断电路。有3种情况可以产生中断,即规则组转换结束注入组转换结束模拟看门狗事件。ADC1和ADC2的中断映射在同一个中断向量上。
    在这里插入图片描述

(3)ADC的相关引脚

在这里插入图片描述
V D D A V_{DDA} V S S A V_{SSA} 应该分别连接到VDD和VSS,传感器信号通过任意一路通道进入ADC并被转换成数字量,该数字量会被存入一个16位的数据寄存器中,在DMA使能的情况下,STM32的存储器可以直接读取转换后的数据ADC必须在时钟ADCCLK的控制下才能进行A/D转换,ADCCLK的值是由时钟控制器控制,与高级外设总线APB2同步。时钟控制器为ADC时钟提供了一个专用的可编程预分频器,默认的分频值为2。

(4)STM32的ADC工作模式

STM32的每个ADC模块可以通过内部的模拟多路开关切换到不同的输入通道并进行转换。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。例如,可以如下顺序完成转换:通道3->通道8->通道2->通道2->通道0->通道2->通道2->通道15。(所谓的通道就是上述的模拟输入信号)

举例:比如要处理环境数据,通道3处理噪声,通道8处理大气污染。。。各司其职。


规则组由多达16个转换组成。规则通道和它们的转换顺序在ADC_SQRx寄存器选择。规则组中转换的总数应写入ADC_SQR1寄存器的L[3:0](4位刚好表示16个转换总数)位中。注入组由多达4个转换组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]位中。如果ADC_SQRx或ADC_JSQR寄存器在转换期间被更改,当前的转换被清除,一个新的启动脉冲将发送到ADC以转换新选择的组。


所谓规则通道就是一个常规的程序从前往后进行执行,在规则通道执行的过程中会存在注入通道,类似于一个中断,也就是说我们先处理注入通道,处理完之后再回到规则通道这里。(注入转换在特殊情况下才会使用,正常情况下我们只需要不断的检测外部数据进行转化,但是有可能我们需要其他不频繁的外部数据,因此我们可能会设置一个按钮,在某些情况下按下按钮使得系统转向采集其他类型的数据,此时称之为注入,这个任务完成之后又回到正常的外部数据采集与转换-也就是又回到了规则通道)
在这里插入图片描述

二、ADC转化模式

1:单次转化模式

单次转换模式下,ADC只执行一次转换。该模式有两种启动方式

  • 既可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动
  • 可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0。然后ADC停止。

一旦选择通道的转换完成

  • 如果一个规则通道被转换,转换数据被储存在16位ADC_DR寄存器中,EOC(转换结束)标志被设置,如果设置了EOCIE,则产生中断。
  • 如果一个注入通道被转换,转换数据被储存在16位的ADC_DRJ1寄存器中,JEOC(注入转换结束)标志被设置,如果设置了JEOCIE位,则产生中断。ADC停止。
  • 在这里插入图片描述

2:连续转换模式

在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。此模式可通过外部触发启动或通过设置ADC_CR2寄存器上的ADON位启动,此时CONT位是1。注意这里,单次转换CONT(continue)位是0,这里是1
每个转换后:

  • 如果一个规则通道被转换,转换数据被储存在16位的ADC_DR寄存器中,EOC(转换结束)标志被设置,如果设置了EOCIE,则产生中断。
  • 如果一个注入通道被转换,转换数据被储存在16位的ADC_DRJ1寄存器中,JEOC(注入转换结束)标志被设置,如果设置了JEOCIE位,则产生中断。
    在这里插入图片描述

注意无论是单次还是连续转换,都是对单个通道进行的转换


3:扫描模式

此模式用来扫描一组模拟通道。扫描模式可通过设置ADC_CR1寄存器的SCAN位(进行写1操作)来选择。

一旦这个位被设置,ADC扫描所有被ADC_SQRX寄存器(对规则通道)或ADC_JSQR(对注入通道)选中的所有通道(我们预设的通道都是保存在上述两个寄存器上)。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了CONT位,转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换(也就是不会到结束位置,通道n连一条边到通道1)。如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入组通道转换的数据总是存储在ADC_JDRx寄存器中。(注入组不能DMA,谨记)

当然扫描模式的通道顺序也是可以设置的。
在这里插入图片描述

4:间断模式

把长序列分割成短序列,依次进行转换。
在这里插入图片描述


规则组
此模式通过设置ADC_CR1寄存器上的DISCEN位激活。它可以用来执行一个短序列n次转换(n<=8),此转换是ADC_SQRx寄存器所选择的转换序列的一部分如果寄存器里有16个通道需要转换,而n=3,那么我们每次只转换n个通道)。数值n由ADC_CR1寄存器的DISCNUM[2:0](0-8,三位就够了)位给出。一组转化结束后,一个外部触发信号可以启动ADC_SQRx寄存器中描述的下一轮n次转换,直到此序列所有的转换完成为止。总的序列长度由ADC_SQR1寄存器的L[3:0]定义。

注意扫描模式一组转化结束后不需要外部触发信号,自动进行下一组的转换,而间断模式需要一个外部的触发信号。


举例: n=3,被转换的通道 = 0、1、2、3、6、7、9、10 第一次触发:转换的序列为 0、1、2 第二次触发:转换的序列为 3、6、7 第三次触发:转换的序列为 9、10,并产生EOC事件(这里产生一个中断就很有意思了,我们可以中断处理接一个定时器,来进行固定间隔的转换) 第四次触发:转换的序列 0、1、2。注意: 当以间断模式转换一个规则组时,转换序列结束后不自动从头开始。 当所有子组被转换完成,下一次触发启动第一个子组的转换。在上面的例子中,第四次触发重新转换第一子组的通道 0、1和2。


注入组
此模式通过设置ADC_CR1寄存器的JDISCEN位激活。在一个外部触发事件后,该模式按通道顺序逐个转换(规则组是短序列,这里是逐个,也就是上面的n=1)ADC_JSQR寄存器中选择的序列。 一个外部触发信号可以启动ADC_JSQR寄存器选择的下一个通道序列的转换,直到序列中所有的转换完成为止。总的序列长度由ADC_JSQR寄存器的L[1:0]位定义。(逐个转换的概念很像扫描模式,不同之处又是这里必须有一个外部触发信号)而为什么用L[1:0]存储呢,因为注入组由4个转换组成,两位即可。


举例: n=1,被转换的通道 = 1、2、3 第一次触发:通道1被转换。第二次触发:通道2被转换。第三次触发:通道3被转换,并且产生EOC和JEOC事件。第四次触发:通道1被转换,等等。

注意:当完成所有注入通道转换,下个触发启动第1个注入通道的转换。在上述例子中,第四个触发重新转换第1个注入通道1。必须避免同时为规则组和注入组设置间断模式。间断模式只能作用于一组转换。


三:其他重要操作

1:校准

ADC有一个内置自校准模式校准可大幅减小因内部电容器组的变化而造成的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。通过设置ADC_CR2寄存器的CAL位启动校准。一旦校准结束,CAL位被硬件复位,可以开始正常转换。建议在上电时执行一次ADC校准。校准阶段结束后,校准码储存在ADC_DR中。

2:数据对齐

ADC_CR2寄存器中的ALIGN位选择转换后数据储存的对齐方式。数据可以左对齐或右对齐。注入组通道转换的数据值已经减去了在ADC_JOFRx寄存器中定义的偏移量,因此结果可以是一个负值,此时必须有一个符号位才能记录,SEXT位就是扩展的符号值。对于规则组通道,不需减去偏移值,因此只有12个位有效。


右对齐
在这里插入图片描述
左对齐
在这里插入图片描述

3:可编程的通道采样时间

ADC使用若干个ADC_CLK周期对输入电压采样,采样周期数目可以通过ADC_SMPR1和ADC_SMPR2寄存器中的SMP[2:0]位更改。每个通道可以分别用不同的时间采样。总转换时间如下计算:TCONV = 采样时间+ 12.5个周期(转化时间);例如: 当ADCCLK=14MHz,采样时间为1.5周期 TCONV = 1.5 + 12.5 = 14周期 = 1μs。

4:外部触发转换

转换可以由外部事件触发(例如定时器捕获,EXTI线)。如果设置了EXTTRIG控制位,则外部事件就能够触发转换。EXTSEL[2:0]和JEXTSEL2:0]控制位允许应用程序选择8个可能的事件中的某一个,可以触发规则和注入组的采样。当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。

A D C 1 A D C 2 ADC1和ADC2用于规则通道的外部触发
在这里插入图片描述
A D C 1 A D C 2 ADC1和ADC2用于注入通道的外部触发
在这里插入图片描述

5:DMA请求

因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用DMA,这可以避免丢失已经存储在ADC_DR寄存器中的数据。只有在规则通道的转换结束时才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户指定的目的地址。

6:温度传感器

温度传感器可以用来测量器件周围的温度(TA)。温度传感器在内部和ADC1_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推荐采样时间是17.1μs。当没有被使用时,传感器可以置于关电模式。注意:必须设置TSVREFE位激活内部通道:ADC1_IN16(温度传感器)和ADC1_IN17(VREFINT)的转换。温度传感器输出电压随温度线性变化,由于生产过程的变化,温度变化曲线的偏移在不同芯片上会有不同(最多相差45°C)。 内部温度传感器更适合于检测温度的变化,而不是测量绝对的温度。如果需要测量精确的温度,应该使用一个外置的温度传感器。

四、STM32的ADC库函数

  1. 函数void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)初始化。
  2. void ADC_StartCalibration(ADC_TypeDef* ADCx)开始指定ADC的校准状态。
  3. void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)使能或者失能指定的ADC的软件转换启动功能。
  4. void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, u8 ADC_Channel, u8 Rank, u8 ADC_SampleTime),设置指定ADC的规则组通道,设置它们的转化顺序和采样时间。ADC_Channel表示选择通道0-通道17;ADC_SampleTime值采样时间为1.5周期、7.5周期、13.5周期、28.5周期、41.5周期、55.5周期、71.5周期和239.5周期。
  5. u16 ADC_GetConversionValue(ADC_TypeDef* ADCx),返回最近一次ADCx规则组的转换结果,例如:u16 DataValue; DataValue = ADC_GetConversionValue(ADC1)。

1:ADC_Init函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2:ADC_StartCalibration校准函数

在这里插入图片描述
未完待续

发布了269 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csyifanZhang/article/details/105673692