模/数转换ADC浅谈(一)

生活中的信号更多的是模拟信号,而智能芯片能直接处理的是数字信号,在这样的背景下,具备将模拟信号以数字形式处理、存储或传输的模/数转换器就必不可少了。为了补充下读者的英语知识,笔者觉得有必要用英文完整解释一下ADC(Analog to Digital Converter),笔者相信大多数攻城狮对ADC的关注,主要集中于分辨率、转换速度、ADC类型、参考电压范围。

笔者主要做过STM32方面的项目,就聊一下在STM32的ADC应用体会吧。笔者觉得STM32在片上集成的ADC外设还是非常强大的,比如在STM32F103xC、STM32F103xD和STM32F103xE增强型产品中,就内嵌了3个12位ADC,每个ADC共用多达21个外部通道,不仅仅可以实现单纯的单次扫描,还可以实现多次扫描转换,可测量多个外部和内部信号源,各通道的A/D转换可以单次、连续、扫描或间断模式执行。经过ADC的结果可以存储在16位数据寄存器中,攻城狮根据自己的喜好可以选择左对齐或者右对齐。攻城狮如果需要检测输入电压是否超出用户定义的高/低阀值,可以模拟看门狗特性应用在程序中。

接下来我们来看一下ADC的架构图吧。

笔者主要从ADC的规则通道转换来分析整个过程。以架构图的中间的模拟至数字转换器(ADC部件)为核心,VREF+、VREF-等四个是ADC参考电压,ADCx_IN0~ADCx_IN15是ADC的输入信号通道,实际上就是攻城狮设定的GPIO引脚。输入信号(比如我们采集的土壤湿度模拟信号)就是经过这些通道被送到ADC部件的,而ADC部件想要开始转换必须接到触发信号的通知,比如EXTI外部触发、定时器触发、软件触发。当ADC部件接收到触发信号后,对输入通道的信号进行采样仍然是离不开ADC预分频器的ADCCLK时钟驱动,这样的情况下才能进行模数转换,转换后的数值被保存到一个16位的规则通道数据寄存器中,通过CPU指令或DMA把它读取到内存(变量),一般笔者用DMA来做这样的事情,因为CPU有更重要的事情去处理,嘿嘿。通常在模数转换之后需要触发DMA请求,或者触发ADC转换结束事件。还有一点,比如前面提到的如果攻城狮配置了模拟看门狗,一旦采集电压大于阈值就会触发看门狗中断。

根据经验,大部分攻城狮使用ADC时都会不间断的去采集大量的数据,此时使用中断已经不切实际了,必须应用DMA功能。

这里笔者根据经验说明一个小知识点。在做ADC的应用中相关的保存转换好的数据的变量一般前面加一个volatile关键字。加上这个关键字的意义在于可以确保每次读取的是最新采集的数据,而不是CPU寄存器的值,如果不加这个关键字就会导致编码器优化后的访问的是CPU寄存器的值,而不是最新的采集数据值,最新的采集数据值是保存在外设寄存器中的。用volatile声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。笔者觉得被DMA控制器改变的变量用volatile来修饰比较好,确保每次读取到的都是实时的ADC转换值。

笔者:Armstrong

2017/2/9