跳到主要内容

ADC模数转换器

1. ADC简介

ADC(Analog to Digital Converter)即模拟数字转换器,可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁,12位逐次逼近型ADC,1μs转换时间,输入电压范围:0-3.3V,转换结果范围:0-4095

有18个输入通道,可测量16个外部和2个内部信号源。

有规则组和注入组两个转换单元,模拟看门狗自动监测输入电压范围。

信息

STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道。

2. 逐次逼近型ADC

Image

该图是ADC0809的图,左边是8路输入开关,通过通道选择开关,选中一路,输入到比较器前面进行转换;地址锁存和译码器,想选中哪个通道,就把通道号放在这三个脚上,然后给一个锁存信号,对应的通路开关就可以自动拨好了。相当于一个可以通过模拟信号的数据选择器。

ADC转换是一个很快的过程,只有微秒左右,不需要多个AD转换器完成工作,只需要设计一个AD转换器和一个多路选择开关即可:想转换哪一路,就先拨一下开关,选中对应通道,然后再开始转换。

STM32有18个输入通道,对应这里就是一个18路输入的多路开关。电压对应的编码数据需要用逐次逼近法获取。

比较器是一个电压比较器,输出一个高低电平指示谁大谁小。两个输入端一个是待测电压(未知编码的电压),另一个是DAC的电压(已知编码的电压)输出端。DAC是数模转换器,内部使用加权电阻网络来实现转换。两个电压同时输入到电压比较器,进行大小判断,如果DAC输出的电压比较大,就调小DAC数据;反之就增大。直到DAC输出电压近似等于外部通道输入的电压。这样DAC输入的数据就是外部编码的数据了。

这个电压调节的过程就是逐次逼近SAR来完成的。为了最快,通常使用二分法进行逼近。

提示

比如8位DAC,编码就是0-255,那么第一次逼近就选取128,然后比较。然后如果大了,就取64,否则取192.以此类推。

这个过程每次取的数字,用二进制表示,正好是二进制每一位的位权。相当于是判断二进制高位-低位是1还是0。

进而简化为判断8次0还是1.

EOC是转换结束信号,START是开始转换,CLOCK是时钟。

DAC的参考电压决定了ADC的输入范围,所以也是ADC参考电压。

通常参考电压的正极和VCC是一样的,会接在一起;参考电压的负极和GND是一样的,也会接在一起。

3. STM32的逐次逼近型ADC

左边是ADC的18个输入通道,包括16个GPIO口,还有一个内部的温度传感器,一个VREFINT内部参考电压。

后头是一个模拟多路开关。输出进入模数转换器。

模数转换器执行逐次比较,结果直接放在数据寄存器,读取结果就能知道ADC转换的结果。

Image

对于普通ADC,多路选择开关只选择一个。但是在该ADC中,可以选择多个,转换时分为两个组:规则通道组和注入通道组,规则组可以一次性最多选16个,规则组选4个。

注意

规则通道数据寄存器只有1个16位的,这是比较尴尬的地方;这意味着,当你需要16个数据的时候,前15个数据都会被丢弃,只能得到第16位。

这个问题的解决方案是配合DMA实现。DMA可以转运我们的数据,保证暂时不被覆盖。

注入组比较高级。一般情况下,使用规则组就可以。

对于STM32的ADC,触发ADC开始转换的信号有两种:

  1. 软件触发,程序中手动调用一条代码,即可触发。
  2. 硬件触发,来自定时器各个通道和TRGO主模式的注入组、规则组的触发源。

ADC经常需要过一个固定时间段转换一次。用定时器每隔1ms申请一次中断,然后在中断里手动转换一次。

危险

但是频繁进中断也会带来些许弊端,如果有很多中断需要频繁进入,那就会影响主程序的执行。不同中断之间,由于优先级不同,那么有些程序肯定不能及时被响应。

所以,对于需要频繁进中断并且只完成简单工作的情况,一般有硬件支持。

比如,可以给TIM3定一个1ms的时间,并且把TIM3的更新事件选择为TRGO输出,在ADC这里,选择开始触发信号为TIM3的TRGO,这样TIM3的更新事件就能通过硬件自动触发ADC转换了。整个过程不需要进中断,节省了资源。此时定时器触发就发挥了较大的作用。

还可以选择外部中断引脚来触发转换。

左上角的电压中,上面两个是参考电压,决定了ADC输入电压的范围,下面两个是ADC的供电引脚,一般情况下,VREF+接VDDA,VREF-接VSSA。在该芯片中,没有VREF的引脚,在内部已经相接。

在这里,VDDA接3.3V,VSSA接0V。

ADCCLK是ADC的时钟,也就是CLOCK,是用于驱动内部逐次比较的时钟,来自于ADC预分频器,来源于APB2时钟通过ADC预分频进行预分频,ADCCLK最大是14MHz,只能选择6/8分频,不然会超出。

DMA请求可以用于触发DMA进行数据转运。

上面有模拟看门狗。一旦触发,就会申请模拟看门狗的中断,最后通向NVIC。

对于规则组和注入组而言,转换完成后也会有一个EOC转换完成的信号,EOC是规则组的完成信号,JEOC是注入组完成的信号。

这两个信号会在状态寄存器里置一个标志位,读取该标志位即知道转换是否结束。

4. ADC基本结构

Image

左边是输入通道,中间是AD转换器,有两个组:规则和注入,转换的结果可以放入AD数据寄存器中。规则组只有1个数据寄存器,注入组有4个,下面有触发控制,提供了开始转换这个START信号。

触发控制可以选择软件触发和硬件触发。

右边是来自于RCC的ADC时钟CLOCK。ADC逐次比较的过程就是由这个时钟推动的。

上面可以布置一个模拟看门狗用于监测转换结果的范围。如果超出设定的阈值,就通过中断输出控制,向NVIC申请中断。

规则、注入组转换完成后会有一个EOC信号。其会置一个标志位,可以通向NVIC。

开关控制就是ADC_Cmd函数,用于给ADC上电。

5. 输入通道

16个通道对应的GPIO口:

Image

ADC1和ADC2的引脚都是相同的,可以分别工作,也可以启用双ADC模式,使其一起工作,组成交叉模式等。

6. 转换模式

  • 单次转换,非扫描模式:

Image

  • 连续转换,非扫描模式:

Image

  • 单次转换,扫描模式:

EOC之前,用DMA及时将数据挪走。

Image

  • 连续转换,扫描模式:

一次转换完成后,立刻开始下一次转换。

Image

在扫描模式下,还有一种间断模式,其作用是在扫描的过程中每隔几个转换就暂停一次,需要再次触发才能继续。

7. 触发控制

AFIO来决定是外部引脚还是来自片上定时器的内部信号。

Image

8. 数据对齐

Image

ADC是12位的,转换结果是12位的。数据寄存器接受的是16位的。但是数据对齐之后,可以变成16位的。

右对齐方法是左边补零,左对齐方法是右边补零。一般使用右对齐。

左对齐把数据左移4位,会把结果乘16,但也发挥一个作用:如果不需要高分辨率,把高8位数据取出来,舍弃后面4位,等价为8位ADC。

9. 转换时间

  • AD转换的步骤:采样、保持、量化、编码

STM32 ADC的总转换时间为:

Tconv=T_{conv} = 采样时间 + 12.5 个ADC周期

ADCCLK=14MHzADCCLK=14MHz,采样时间为1.5个ADC周期,Tconv=1.5+12.5=14T_{conv}=1.5+12.5=14个ADC周期,即1μs。

如果将ADCCLK设置超过14MHz,就是在超频工作,转换时间可以短于1μs。但舍弃了部分稳定性。

10. 校准

Image

11. 硬件电路

Image

第一个是电位器产生可调电压的电路,一端接3.3V,一端接GND,中间滑动端可以提供0-3.3V的可变电压。接ADC的输入通道,比如PA0口。阻值太小,电阻通过电流会很大,可能炸掉;至少要接KΩ级的电阻。

第二个是传感器输出电压的电路,一般来说,像光敏电阻、热敏电阻等等,都可等效为一个可变电阻,可以通过和一个固定电阻串联分压,来得到一个反应电阻值电压的电路。固定电阻可以选用和传感器相近的阻值,可以得到一个位于中间电压区域比较好的输出。

第三个是一个简单的电压转换电路,把0-5V的转换为0-3.3V,进入ADC转换。