打印
[其他ST产品]

STM32F1常用外设介绍

[复制链接]
楼主: 范德萨发额
手机看帖
扫描二维码
随时随地手机跟帖
141
范德萨发额|  楼主 | 2023-2-28 20:23 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
18个输入通道,可测量16个外部和2个内部信号源,外部信号源就是16个GPIO口,在引脚上直接模拟信号就行了,不需要任何的额外电路引脚就能直接测电压,2个内部信号源是内部温度传感器和内部参考电压,温度传感器可以测量CPU的温度,内部参考电压是一个1.2V左右的基准电压,这个基准电压不随外部供电电压变化而变化,如果芯片的供电不是标准的3.3V测量外部引脚的电压就可能不对,这时可以读取基准电压进行校准,这样就可以得到正确的电压值了。

规则组和注入组两个转换单元,这个是STM32 ADC的增强功能,普通AD转换流程是,启动一次转换,读一次值,然后再启动,在读值,这样的流程,但是STM32的ADC可以列一个组,连续转换多个值,一次性启动一个组,连续转换多个值,并且有两个组,一个是用于常规使用的规则组,一个是用于突发事件的注入组。、

使用特权

评论回复
142
范德萨发额|  楼主 | 2023-2-28 20:24 | 只看该作者
模拟看门狗自动检测输入电压范围,此ADC一般可以用于测量光线强度、温度,经常会要求光线高于某个阈值、低于某个阈值,或者温度高于某个阈值,低于某个阈值时,执行一些操作,高于某个阈值,低于某个阈值的判断,就可以用模拟看门狗来自动执行,模拟看门狗可以检测指定的某些通道,当AD值高于它设定的上阈值或者下阈值时,就会申请中断,就可以在中断函数中执行相应的操作,这样就不用手动读值,再用if判断了

STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道,最多只能测量10个外部引脚的模拟信号

使用特权

评论回复
143
范德萨发额|  楼主 | 2023-2-28 20:24 | 只看该作者
逐次逼近型ADC的内部结构



这个图是ADC0809的内部结构图

使用特权

评论回复
144
范德萨发额|  楼主 | 2023-2-28 20:24 | 只看该作者
它是一个独立的8位逐次 逼近型ADC芯片,左边IN0~到IN7,是8路输入通道,通过通道选择开关,选中一路,输入到比较器上方进行转换,下面部分是地址锁存和译码,就是想选中哪一路,就把通道号放在这三个引脚上,然后给一个锁存信号,上面对应的通路开关就自动拨好了,相当于可以通过模拟信号的数据选择器,因为ADC转换是一个非常快的过程,给个开始信号,过个几个us就转换完成了想转换多路信号,那不必设计多个AD转换器,只需要一个AD转换器,然后加一个多路选择开关,想转换哪一路,选中对应通道,然后再开始转换就行了,这就是输入通道选择的部分,这个ADC0809只有8个输入通道,STM32内部的ADC是有18个输入通道,对应的是18路输入的多路开关,输入信号选好后,到电压比较器,它可以判断两个输入信号电压的大小关系,输出一个高低电平指示谁大谁小,它的两个输入端,一个是待测的电压,另一个是DAC的电压输出端,DAC是数模转换器,给一个数据,就可以输出数据对应的电压,DAC内部是适应加权电阻网络来实现的转换,将外部输入的未知的电压和一个已知输出的电压,两个同时输入到电压比较器,进行大小判断,如果DAC输出的电压比较大,就调小DAC数据,如果DAC输出的电压比较小,就增大DAC数据,直到DAC输出的电压和外部通道输入的电压近似相等,这样DAC输入的数据就是外部电压的编码数据了,这就是DAC的实现原理,电压调节的过程是逐次逼近SAR来完成的,为了最快找到未知电压的编码,通常会使用二分法进行寻找,EOC(End Of Convert)是转换结束信号,START是开始转换,给一个输入脉冲,开始转换,CLOCK是ADC时钟,因为ADC内部是一步一步进行判断的,所以需要时钟来推动这个过程,下面VREF+和VREF-是DAC的参考电压,例如给一个数据255,是对应5V还是3.3V就由参考电压决定,这个DAC的参考电压也决定了,ADC的输入范围,所以他也是ADC参考电压,左边是整个芯片电路的供电,VCC和GND,通常参考电压的VCC是一样的,会接在一起,参考电压的负极和GND也是一样的,也接到一起,一般情况下ADC输入电压的范围就和ADC的供电是一样的。

使用特权

评论回复
145
范德萨发额|  楼主 | 2023-2-28 20:25 | 只看该作者
STM32的ADC:

左边是ADC的输入通道、包括16个GPIO口,IN0~IN15,和两个内部的通道,一个是内部温度传感器,另一个是VREFINT(V Reference Internal),内部参考电压,总共是18个输入通道,然后到达模拟多路开关,可以指定想要的通道,右边是多路开关的输出,进入到模数转换器,转化结果会放在数据寄存器中,读取寄存器就能知道ADC转换的结果了,对于普通的ADC,多路开关一般都是只选中一个的,就是选中某个通道、开始转换、等待转换完成、取出结果,这是普通的流程,但是STM32就可以同时选中多个,在转换的时候,还分成了两个组,规则通道组和注入通道组,规则组可以一次最多选中16个通道,注入组最多可以选中4个通道,就像是去餐厅点菜,普通的ADC是,你指定一个菜,老板给你做,然后做好了送给你,而这里是,你指定一个菜单,这个菜单最多可以填16个菜,然后直接递个菜单给老板,老板就按照菜单的顺序依次做好,一次性给你端上来,这样的话就可以大大提高效率,当然菜单也可以只写一个菜,这样这个菜单就简化成普通模式了,对于这个菜单也有两种,一种是规则组菜单,可以同时上16个菜,但是规则组只有一个数据寄存器,就是桌子比较小,最多只能放一个菜,如果上16个菜,前15个菜都会被挤掉,只能的到第16个菜,所以对于规则组转换来说,如果使用这个菜单的话,最好配合DMA来实现,DMA是一个数据转运小帮手,它可以在每上一个菜之后,把这个菜挪到其他地方去,防止被覆盖,规则组虽然可以同时转换16个通道,但是数据寄存器只能存一个结果,如果不想之前的结果被覆盖,那在转换完成之后,就要尽快把结果拿走,注入组,相当于是餐厅的VIP座位,在这个座位上一次最多可以点4个菜,并且数据寄存器有4个可以同时上4个菜,对于注入组而言,就不用担心数据覆盖的问题了,这就是规则组和注入组的介绍,一般情况下,使用规则组就足够了,如果要使用规则组的菜单,那就配合DMA转运数据,这样就不用担心数据覆盖的问题了。

使用特权

评论回复
146
范德萨发额|  楼主 | 2023-2-28 20:25 | 只看该作者
对于规则组,左下角是触发的部分,对于STM32的ADC触发开始转换的信号有两种,一种是软件触发,就是在程序中手动调用一条代码,就可以启动转换了,另一种是硬件触发,就是触发源,触发源主要是来自定时器,有定时器的各个通道,还有TRGO定时器主模式的输出,(定时器可以通向ADC、DAC这些外设,用于触发转换),ADC经常需要过一个固定时间段转换一次,比如每隔1ms转换一次,正常的思路就是,用定时器,每隔1ms申请一次中断,在中断里手动开启一次中断,这样也是可以的,但是频繁进中断对程序是有一定影响的,如果有很多中断都需要频繁进入,那将会影响主程序的执行,并且不同中断之间,由于优先级的不同,也会导致某些中断不能及时的到响应,如果触发ADC的中断不能及时响应,那ADC的转换频率就会产生影响,所以对于需要频繁进中断,并且只在中断里只完成了简单的工作的情况,一般都会有硬件的支持,可以给TIM3定一个1ms的时间,把TIM3的更新事件选择为TRGO输出,然后再ADC这里,选择触发信号TIM3的的TRGO,这样TIM3的更新事件就能通过硬件自动触发ADC转换了,整个过程不需要进中断,节省了中断资源,这就是定时器触发的作用,也可以选择外部中断引脚来触发中断,都可以在程序中配置,左上角是VREF+、VREF-、VDDA和VSSA,VREF+、VREF-这两个是ADC的参考电压,决定了ADC输入电压的范围,VDDA和VSSA是ADC的供电引脚,一般情况下VREF+要接VDDA,VREF-要接VSSA,STM32没有VREF+、VREF-的引脚内内部已经和VDDA和VSSA接在一起了。VDDA和VSSA是内部模拟部分的电源,例如ADC、RC震荡器、锁相环等,在STM32中VDDA接3.3V,VSSA接GND,所以输入电压的范围就是0~3.3V,右边的ADCCLK是ADC的时钟,也就是ADC0809中的CLOCK,是用于驱动内部逐次比较的时钟来自ADC预分频器,ADC预分频器来源于RCC,APB2时钟72MHz,然后通过ADC进行分频,得到ADCCLK,ADCCLK最大是14MHz,对于ADC预分频器,只能选择6分频,结果是12MHz和8分频结果是9MHz,上面的是DMA请求,用于触发DMA进行数据转运,再上面是两个数据寄存器,用于存放转换结果,在上面是模拟看门狗,它们可以存一个阈值高限和阈值低限,如果启动了模拟开门狗,并且指定了看门的通道,那么看门狗就会关注它看门的通道,一但超过这个阈值范围,就会乱叫,就会在上面申请一个模拟看门狗的中断,最后通向NVIC,对于规则组和注入组,它们转换完成后,也会有一个EOC转换完成的信号,EOC是规则组完成的信号,JEOC是注入组完成的信号,这两个信号会在状态寄存器置一个标志位,读取这个标志位,就能知道是不是转换结束了,同时这两个标志位也可以去到NVIC,申请中断,如果开启了NVIC对应的通道,它们就会触发中断。

使用特权

评论回复
147
范德萨发额|  楼主 | 2023-2-28 20:25 | 只看该作者
ADC基本结构

左边是输入通道,16个GPIO口,外加两个内部的通道,然后进入AD转换器,AD转换器里有两个组,一个是规则组,一个是注入组,规则组最多可以选择16个通道,注入组最多可以选择4个通道,转换的结果有放在AD数据寄存器中,其中规则组只有1个数据寄存器,注入组有4个数据寄存器,下面是触发控制,提供开始转换的的START信号,触发控制可以选择软件触发和硬件触发,硬件触发主要是来自于定时器,当然也可以选择外部中断的引脚,右边是来自RCC的ADC时钟CLOCK,ADC逐次比较的过程就是由此时钟推动,上面可以布置一个模拟看门狗用于检测转换的结果的范围,如果超出设定的阈值,就通过中断输出控制,向NVIC申请中断,规则组和注入组在转换完成后会有个EOC信号,会置一个标志位,也可以通向NVIC,右下角是开关控制,在库函数中,就是ADC_Cmd函数,用于ADC上电的。

使用特权

评论回复
148
范德萨发额|  楼主 | 2023-2-28 20:26 | 只看该作者
输入通道:

使用特权

评论回复
149
范德萨发额|  楼主 | 2023-2-28 20:26 | 只看该作者
双ADC模式:就是ADC1和ADC2一起工作,可以配合组成同步模式,交叉模式等等模式,交叉模式就是ADC1和ADC2交叉的对一个通道进行采样,这样可以提高采样率。

使用特权

评论回复
150
范德萨发额|  楼主 | 2023-2-28 20:27 | 只看该作者
规则组的四种转换模式
单次转换、非扫描模式

使用特权

评论回复
151
范德萨发额|  楼主 | 2023-2-28 20:27 | 只看该作者
规则组的四种转换模式
单次转换、非扫描模式

使用特权

评论回复
152
范德萨发额|  楼主 | 2023-2-28 20:27 | 只看该作者
在非扫描模式下,这个菜单只有第一个序列1的位置有效,这时菜单同时选择一组的方式就退化成简单的选中一个的方式了,我们可以在序列1的位置指定我们想转换的通道,比如通道2,然后就可以触发转换,ADC就会对这个通道2进行模数转换,过一小段时间后,转换完成,转换结果放在数据寄存器里,同时给EOC标志位置1,整个转换过程就结束了。判断这个标志位,如果转换完了,就可以在数据寄存器中读取结果了。如果想再启动一次转换,那就需要再触发一次。转换结束,置EOC标志位,读结果。如果想换一个通道转换,那在转换之前,把第一个位置通道2改成其他通道,然后再启动转换。

使用特权

评论回复
153
范德萨发额|  楼主 | 2023-2-28 20:27 | 只看该作者
连续转换、非扫描模式

使用特权

评论回复
154
范德萨发额|  楼主 | 2023-2-28 20:28 | 只看该作者
非扫描模式,所以菜单列表就只用第一个,与上次单次转换不同的是,它在一次转换结束后不会停止,而是立刻开始下一轮转换,然后一直持续下去,这样就只需要触发一次,之后就可以一直转换了。这个模式的好处就是,开始转换之后不需要等待一段时间,它一直都在转换,不需要手动开启转换了。也不用判断是否结束,想要读AD值的时候,就直接从数据寄存器取就行。

使用特权

评论回复
155
范德萨发额|  楼主 | 2023-2-28 20:28 | 只看该作者
单次转换、扫描模式

image-20221228172651369

这个模式也是单次转换,所以每触发一次,转换结束后,就会停下来,下次转换就得再触发才能开始,他是扫描模式,这就会用到这个菜单列表了,可以在菜单里点菜,比如第一个菜是通道2,第二个菜是通道5,等等,这里每个位置是通道几可以任意指定,并且也是可以重复的,初始化结构体里还有个参数,就是通道数目,因为这16个位置可以不用完,只用前几个,那就需要再给个通道数目的参数,告诉他,我有几个通道,这里指定通道7,那它就只看前7个位置,然后每次触发之后,它就依次对前7个位置进行AD转换,转换结果都放在数据寄存器中,为了防止数据被覆盖,就需要用DMA及时将数据挪走,7个通道转换完成后,产生EOC信号,转换结束,然后再触发下一次,就又开始新一轮的转换,这就是单次转换,扫描模式的工作流程。

使用特权

评论回复
156
范德萨发额|  楼主 | 2023-2-28 20:28 | 只看该作者
连续转换、扫描模式

在上一次模式的基础上,可以在一次转换完成后,立刻开始下一次的转换。在扫描模式的情况下,还可以右边一种模式,叫间断模式,它的作用是,在扫描的过程中,每隔几个转换,就暂停一次,需要再次触发,才能继续

使用特权

评论回复
157
范德萨发额|  楼主 | 2023-2-28 20:29 | 只看该作者
触发控制:


这个表就是规则组的触发源,在这个表里有来自定时器的信号,还有来自引脚或者定时器的信号,具体是引脚还是定时器,需要AFIO重映射来确定,最后是软件控制位,也就是软件触发,这些触发信号可以配置右边的寄存器来完成,库函数直接给一个参数就行。

使用特权

评论回复
158
范德萨发额|  楼主 | 2023-2-28 20:33 | 只看该作者
数据对齐

image-20221228174146250

这个ADC是12位的,它的转换结果就是一个12位的数据,但是这个数据寄存器是16位的,所以就存在一个数据对齐的问题,分为两种对齐方式,数据右对齐,和数据左对齐,数据右对齐就是12位的数据向右靠,高位多出来的几位就补0,第二种是数据左对齐,是12位的数据向左靠,低位多出来的几位就补0,我们一般使用的都是数据右对齐,这样读取这个16位寄存器,直接就是转换结果,如果选择左对齐,直接读的话,得到的数据会比实际的大,因为数据左对齐实际上就是把数据左移了4次,二进制的数据,数据左移一次,就等效于把这个数据乘2,左移4次,就相等于把结果乘16了,所以直接读会比实际值大16倍,左对齐的作用就是,不需要高分辨率时,就可以选择左对齐再把后面的低4位去掉,这个12位的ADC就退化成8位的ADC了。

使用特权

评论回复
159
范德萨发额|  楼主 | 2023-2-28 20:33 | 只看该作者
转换时间

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

STM32 ADC的总转换时间为:Tconv = 采样时间(采样保持花费的时间,采样时间越大,越能避免一些毛刺信号的干扰)+12.5个ADC周期(量化编码花费的时间)

例如:当ADCCLK = 14MHz,采样时间为1.5个ADC周期,Tconv = 1.5 + 12.5 = 14个ADC周期 = 1us

使用特权

评论回复
160
范德萨发额|  楼主 | 2023-2-28 20:34 | 只看该作者
校准

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正值(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差

建议在每次上电后执行一次校准

启动校准前,ADC必须处于关电状态超过至少两个ADC时钟周期。

只需要在ADC初始化最后加几条代码即可

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则