赞
踩
单片机学习!
目录
GPIO只能读取引脚的高低电平,只有两个值:高电平或低电平。而ADC可以对高电平和低电平之间的任意电压进行量化,最终用一个变量来表示。读取这个变量就可以知道引脚的具体电压是多少。ADC好比一个电压表,可以把引脚的电压值测出来,放在一个变量里。
- ADC(Analog-Digital Converter)模拟-数字转换器
- ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
- 12位逐次逼近型ADC,1us转换时间
- 输入电压范围:0~3.3V,转换结果范围:0~4095
- 18个输入通道,可测量16个外部和2个内部信号源
- 规则组和注入组两个转换单元
- 模拟看门狗自动监测输入电压范围
- STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
ADC模拟到数字转换器,简称模数转换器或者AD转换器。
ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量。建立模拟电路到数字电路的桥梁。
STM32主要是数字电路,数字电路只有高低电平,没有几伏电压的概念。要想读取电压值,就需要借助ADC模拟转换器来实现了。ADC读取引脚上的模拟电压,转换为一个数据,存在寄存器里,再把这个数据读取到变量里来就可以进行显示、判断、记录等操作了。
ADC是模拟到数字的桥梁,DAC是数字到模拟的桥梁。DAC数字模拟转换器,使用DAC就可以将数字变量转换为模拟电压。DAC主要应用在波形生产这些领域,如信号发生器、音频解码芯片等。
还有一个数字到模拟的桥梁是PWM,PWM可以控制LED的亮度、电机的速度等。PMW只有完全导通和完全断开两种状态,这两种状态都没有功率损耗,所以在直流电机调速这种大功率的应用场景使用PWM来等效模拟量是比DAC等好的选择,并且PWM电路更加简单,更加常用,所以PWM的应用空间比DAC更广。
STM32的ADC是12位逐次逼近型ADC,1us转换时间。
逐次逼近型是ADC的工作模式,下文展开描述。
12位和1us转换时间涉及到ADC的两个关键参数。
第一个是分辨率,一般用多少位来表示,12位AD值,它的表示范围就是0到2的12次方减1,就是量化结果的范围是0~4095,位数越高量化结果就越精细,对应分辨率就越高。
第二个是转换时间,就是转换频率,AD转换是需要花一小段时间的,这里1us就表示从AD转换开始到产生结果,需要花1us的时间,对应AD转换的频率就是1MHz。1MHz就是STM32 ADC的最快转换频率。如果需要转换一个频率非常高的信号,就需要考虑一下这个转换频率是不是够用;如果信号频率比较低那最大1MHz的转换频率也完全够用。
输入电压范围:0~3.3V,转换结果范围:0~4095。
ADC的输入电压一般要求都是要在芯片供电的负极和正极之间变化的。
0V对应0,3.3V对应4095,中间都是一一对应的线性关系,计算起来比较简单,可直接乘除一个系数就行了。
ADC有18个输入通道,可测量16个外部和2个内部信号源。
外部信号源就是16个GPIO口,在引脚上直接接模拟信号就行了,不需要任何额外的电路,引脚就直接能测电压。
2个内部信号源是内部温度传感器和内部参考电压。温度传感器可以测量CPU的温度,如电脑可以显示一个CPU温度,就可以用ADC读取这个温度传感器来测量。内部参考电压是一个1.2V左右的基准电压,这个基准电压是不随外部供电电压变化而变化的。如果芯片的供电不是标准的3.3V,那测量外部引脚的电压可能就不对。这时就可以读取这个基准电压进行校准,校准后可得到正确的电压值了。
规则组和注入组两个转换单元,这个是STM32 ADC的增强功能,普通的AD转换流程是,启动一次转换、读一次值,然后再启动、再读值,这样的流程。而STM32的ADC就比较高级,可以列一个组,一次性启动一个组,连续转换多个值。并且有两个组可以启动,一个是用于常规使用的规则组;一个是用于突发事件的注入组。
模拟看门狗自动监测输入电压范围。
ADC一般可以用于测量光线强度、温度这些值。并且经常会有个需求:如果光线高于某个阈值或低于某个阈值;温度高于某个阈值或低于某个阈值时。需要执行一些操作。高于某个阈值、低于某个阈值的判断,就可以用模拟看门狗来自动执行。
模拟看门狗可以监测指定的某些通道,当AD值高于它设定的上阈值或者下阈值时,就会申请中断,可以在中断函数里执行相应的操作。执行这个操作可以不用不断手动读值,再用if进行判断了。
STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道。
STM32F103C8T6 ADC资源有ADC1、ADC2 共两个ADC外设。10个外部输入通道也就是它最多只能测量10个外部引脚的模拟信号。上文所说ADC有16个外部信号源,这是这个系列最多有16个外部信号源,但是STM32F103C8T6芯片引脚比较少,有很多引脚没有引出来,所以只有16个外部信号源。
了解逐次逼近型ADC如何测电压,需要先了解逐次逼近型ADC的内部结构,以下结构图和STM32的ADC原理是一样的,它是ADC0809的内部结构图。ADC0809是一个独立的8位逐次逼近型ADC芯片。在单片机性能还不够强的时候,需要外挂一个ADC芯片才能进行AD换, ADC0809就是一款比较经典的ADC芯片。现在单片机的性能和集成度都有很大的提升,很多单片机内部就已经集成了ADC外设,不用外挂芯片,引脚可以直接测电压。
(1)IN0~IN7是8路输入通道。通过(2)通道选择开关,选中输入通道其中一路输入进行转换。(3)地址锁存和译码可以将选中通道的通道号放在(4)ADDA、ADDB、ADDC三个引脚上,然后给一个锁存信号(5)ALE,对应选中的输入通道通路开关就可以自动拨好了。ADDA、ADDB、ADDC三个引脚就是用来控制通道选择开关选择哪一路通道输入的。
这部分就相当于一个可以通过模拟信号的数据选择器。因为ADC转换是一个很快的过程,给个开始信号,过几个us就能转换完成。所以如果要转换多路信号,不用设计多个AD转换器,只需要一个AD转换器再加一个多路选择开关。需要转换哪一路就拨一下多路选择开关选中对应通道,然后再开始转换。
以上就是输入通道选择的部分,ADC0809芯片只有8个输入通道,STM32内部的ADC有18个输入通道,对应通道选择开关就是一个18路输入的多路开关。
输入信号选好后怎么能得出电压对应的编码数据是多少呢?这里需要用逐次逼近的方法来一一比较。(6)电压比较器可以判断两个输入电压的大小关系。输出一个高低电平指示谁大谁小,电压比较器的两个输入端,一个是选中输入通道的带测电压,另一个是DAC的电压输出端。DAC是数模转换器,给DAC一个数据,DAC就可以输出数据对应的电压。DAC内部是使用加权电阻网络来实现的转换。
有一个外部通道输入的未知编码的电压,还有一个DAC输出的已知编码的电压。将两个电压同时输入到电压比较器,进行大小判断。
直到DAC输出的电压和外部通道输入的电压近似相等。这样DAC输入的数据就是外部电压的编码数据了,这就是DAC实现的原理,电压调节的过程就是(7)逐次逼近SAR来完成的。
为了最快找到未知电压的编码,通常会使用二分法进行查找。这里ADC0809芯片是8位的ADC,那编码就是从0~255.举例一个未知电压在0~5V之间。
若未知电压比5/2V的电压小
若未知电压比5/4V的电压大
............
一直进行到第八次比较后,得出与未知电压近似的电压值。
分析发现,在对电压编码进行二等分的时候,就是转化为二进制的数值1000 0000从左到右依次判断:
二进制的8位数值每一位依次判断完后,得到的数值就是未知电压的近似编码电压。
AD转换结束后,(8)DAC的输入数据就是未知电压的编码。
通过(9)8位三态锁存缓冲器进行输出,8位就有8根线,12位就有12根线。
输入一个未知电压,再用DAC输出一个已知电压和输入的未知电压比较。如果未知电压大,就将DAC输出调高;如果未知电压小,就将DAC输出调低。多次调节后DAC调节得到一个和未知电压接近相等的已知电压,最终得到的已知的DAC电压值就可以表示为未知电压的值。
ADC输入通道共18个,包括了16个GPIO口(ADCx_IN0 ~ ADCx_IN15)和两个内部的通道(一个是内部温度传感器,另一个是VREFINT < V Reference Interna l> ,内部参考电压)。
信号经过输入通道后到达模拟多路开关,模拟多路开关可以指定需要选择的通道。模拟多路开关右边是多路开关的输出,信号从多路开关进入到数模转换器(模拟至数字转换器)。这里数字模拟转换器执行的就是上文中电压逐次比较的过程。
转换结果会直接放在数据寄存器里,读取数据寄存器就知道ADC转换的结果了。
这就像是去餐厅点菜。
普通的ADC是,客人指定一个菜,厨师给你做,然后做好了端给客人;
高级的ADC规则通道就是,客人指定一个菜单,这个菜单最多可以点16个菜,然后客人可以直接把菜单给厨师,厨师就按照菜单的顺序依次做好,一次性给客人端上桌。这样可以很大的提升效率。当然菜单也可以只写一个菜,这样菜单就简化成普通的模式了。对于菜单也分为两种:
总结:
规则组虽然可以同时转换16个通道,但是规则组的数据寄存器只能存一个结果,如果不想之前的结果被覆盖,那在转换完成之后,就要尽快把结果拿走。
注入组可以同时转换4个通道,注入组的寄存器有4个,对于注入组来说不用担心数据覆盖的问题。
一般情况下使用规则组就足够了,如果要使用多个通道,就再配合DMA转运数据,解决数据覆盖的问题。下文主要介绍规则组的操作。
触发转换的这部分也就是上文2.4中的START信号,开始转换。STM32的ADC,触发ADC开始转换的信号有两种。
硬件触发的触发源主要是来自于定时器。触发源有定时器的各个通道,还有TRGO定时器主模式的输出。定时器可以通向ADC、DAC这些外设,用于触发转换。
因为ADC经常需要过一个固定时间段转换一次。比如每隔1ms转换一次,一般的思路就是,用定时器,每隔1ms申请一次中断。在中断里手动开始一次转换,但是频繁进中断对程序是有一定影响的。中断频繁进入肯定会对主程序的执行有影响。并且不同中断之间由于优先级的不同也会导致某些中断不能及时得到相应。如果触发ADC的中断不能及时响应,那ADC的转换频率就肯定会受到影响了。
对于ADC转换这种需要频繁进中断,并且在中断里只完成了简单工作的情况一般都会有硬件的支持。在ADC触发转换的这里,就可以给TIM3定个1ms的时间,并且把TIM3的更新事件选择为TRGO输出,然后再ADC这里选择开始触发信号为TIM3的TRGO,这样TIM3的更新事件就能通过硬件自动触发ADC转换了。整个过程不需要进中断,节省了中断资源。这就是定时器触发的作用。
当然在EXTI_11这里还可以选择外部中断引脚来触发转换,都可以在程序中配置。
1.VREF+和VREF-是ADC的参考电压,决定了ADC输入电压的范围。VDDA和VSSA是ADC的供电引脚。一般情况下VREF+要接VDDA,VREF-要接VSSA。在STM32F103C8T6芯片上没有VREF+和VREF-的引脚,它们在芯片内部就已经和VDDA、VSSA接在一起了。VDDA和VSSA在引脚定义表也可以找到:
VDDA和VSSA是内部模拟部分的电源,如ADC、RC振荡器、锁相环等。VDDA接3.3V,VSSA接GND,所以ADC的输入电压范围就是0~3.3V.
2.ADCCLK是ADC的时钟,也就是上文2.2中的CLOCK,用于驱动内部逐次比较的时钟。ADCCLK来自于ADC预分频器,这个ADC预分频器又来源于RCC。
APB2时钟72MHz,通过ADC预分频器进行分频,得到ADCCLK,ADCCLK最大是14MHz,所以ADC预分频器的选择需要注意,ADC预分频器可以选择2、4、6、8分频。如果选择2分频,72M / 2 = 36M,超出允许范围了;选择4分频之后是18M,也超了;选择6分频,结果是12M,没超;8分频,结果是9M,也没超。所以对于ADC预分频器只能选择6分频和8分频这两个值。这一点在程序中需要注意。
3.DMA请求,是用于触发DMA进行数据转运的。
4.注入通道数据寄存器和规则通道数据寄存器,这两个数据寄存器,用于存放转换结果的。
5.模拟看门狗,这里面可以存一个阈值高限和阈值低限。如果启动了模拟看门狗,并指定了看门的通道,那看门狗就会关注它看门的通道,一旦超过这个阈值范围了,看门狗就会乱叫,就是在这里申请一个模拟看门狗的中断,最后通向NVIC。
6.对于规则组和注入组而言,它们转换完成之后,也会有一个EOC转换完成的信号。EOC是规则组的完成信号;JEOC是注入组的完成信号。这两个组会在状态寄存器里置一个标志位,读取这个标志位就可以知道是不是转换结束了。同时这两个标志位也可以去到NVIC申请中断。如果开启了NVIC对应的通道,就会触发中断。
最左边是输入通道,16个GPIO口,外加两个内部的通道。然后进入AD转换器,AD转换器里有两个组,一个是规则组,一个是注入组。规则组最多可以选择16个通道;注入组最多可以选择4个通道。转换的结果可以存放在AD数据寄存器里,其中规则组只有一个数据寄存器,注入组有4个数据寄存器。
AD转换器左下方有触发控制,提供了开始转换START信号。触发控制可以选择软件触发和硬件触发。硬件触发主要是来自于定时器,也可以选择外部中断的引脚。AD转换器右下方是来自于RCC的ADC时钟CLOCK,ADC逐次比较的过程就是由这个时钟推动的。
布置模拟看门狗可以用于监测转换结果的范围,如果超出设定的阈值,就通过中断输出控制,向NVIC申请中断。
规则组和注入组转换完成后会有个EOC信号,EOC信号会置一个标志位,也可以通向NVIC.
右下角的开关控制在库函数中就是ADC_Cmd函数,用于给ADC上电的。
以上就是今天要讲的内容,本文仅仅简单介绍了STM32的ADC数模转换器的原理于内部电路结构。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。