STMCU小助手
发布时间:2022-1-2 08:00
|
一、ADC简介2 ~5 \. n& E* F5 B+ q# r8 b% r Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。2 H3 w3 U1 T' V, W% B9 W) W7 ~ % t% o6 h1 J, @0 Z8 x# ` STM32ADC简介% ?) i$ o4 a# D, `5 G* g9 } STM32 拥有 1~3 个 ADC,ADC1和ADC2紧密耦合,可在双模式下工作(ADC1为主模式)。每个ADC由一个12位逐次逼近的模数转换器组成。每个ADC有多达19个多路复用通道。各种通道的A/D转换可以在单一、连续、扫描或不连续模式下执行。ADC的结果是存储在左对齐或右对齐的16位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。7 h" W0 j' e4 }9 B" B( l% J5 I - s' e8 W# W+ H1 _& l) j ADC工作框图(根据STM32F1的ADC框图介绍STM32L4系列的ADC,大部分相同,有些寄存器有所变动)% N9 }6 b4 I' E) p. u7 o# t
下面根据上图一一介绍* p" X! ~9 x5 t" H7 u) ], X : y4 P6 K8 D; o STM32L4ADC寄存器表
1.电压输入范围: $ p/ }/ s8 e9 I" a6 }
ADC输入范围为: VREF- <= VIN <= VREF+。由 VREF-、VREF+ 、VDDA 、VSSA、这四个外部引脚决定。一般把 VSSA 和 VREF-接地,把 VREF+和 VDDA 接 3V3,得到ADC 的输入电压范围为:0~3.3V。如果我们想让输入的电压范围变宽,去到可以测试负电压或者更高的正电压,我们可以在外部加一个电压调理电路,把需要转换的电压抬升或者降压到 0~3.3V,这样 ADC 就可以测量了。不要直接将高于 3.3V 的电压接到 ADC 管脚上,那样将可能烧坏芯片。 3 v( r+ F; j3 C, I+ b 2.通道转换顺序 信道选择(SQRx、JSQRx)* j4 F9 X+ t4 {. \* w - p- l( R9 G2 r/ `1 ?& w+ y 每个ADC最多有19个多路复用通道:5个来自GPIO板的快速模拟输入(ADCx_INP/INN[1..5]),来自GPIO PADS的多达11个慢模拟输入(ADCx_INP/INN[6..16]). Q: p( i$ B3 k7 [$ b; H ADC连接到以下内部模拟输入:内部参考电压(VREFINT)连接到ADC1_INP0/INN0。内部温度传感器(VTS)连接到ADC1_INP17/INN17。vbat监控通道(vbat/3)连接到ADC1_INP18/INN18。DAC1内部通道连接到ADC1_INP/INN17。 0 o* p8 R- ^* B 规则通道组序列寄存器有 3 个,分别是 SQR3、 SQR2、 SQR1。 SQR3 控制着规则序列中的第一个到第六个转换,对应的位为:SQ1[4:0]~SQ6[4:0],第一次转换的是位 4:0 SQ1[4:0],如果通道 3 想第一次转换,那么在 SQ1[4:0]写 3即可。SQR2 控制着规则序列中的第 7 到第 12 个转换,对应的位为:SQ7[4:0]~SQ12[4:0],如果通道 1 想第 8 个转换,则 SQ8[4:0]写 1 即可。SQR1 控 制 着 规 则 序 列 中 的 第 13 到 第 16 个 转 换 , 对 应 位 为 :SQ13[4:0]~SQ16[4:0],如果通道 6 想第 10 个转换,则 SQ10[4:0]写 6 即可。具体使用多少个通道,由 SQR1 的位 L[3:0]决定,最多 16 个通道。 ) e, O( |; ?1 c/ q* V 注入通道组序列寄存器只有一个,是 JSQR。它最多支持 4 个通道,具体多少个由 JSQR 的 JL[2:0]决定。注意:9 @+ n% C9 ?) I/ N 当 JL[1:0] = 3(有 4 次注入转换)时, ADC 将按以下顺序转换通道:JSQ1[4:0]、JSQ2[4:0]、 JSQ3[4:0] 和 JSQ4[4:0]。2 v# _6 B: F9 v( c, ~ R& J9 {) A# E0 B7 x+ r 当 JL = 2 (有 3 次注入转换)时,ADC 将按以下顺序转换通道:JSQ2[4:0]、JSQ3[4:0] 和 JSQ4[4:0]。 ' h, N! b5 O# G) I; q! z 当 JL = 1 (有 2 次注入转换)时,ADC 转换通道的顺序为:先是 JSQ3[4:0],而后是 JSQ4[4:0]。 当 JL = 0(有 1 次注入转换)时, ADC 将仅转换 JSQ4[4:0] 通道。2 J( Q# b! { [" J7 b6 N2 ^% l ( @" K$ S# W) {* i4 M, g+ I# Z 如果在转换期间修改 ADC_SQRx 或 ADC_JSQR 寄存器,将复位当前转换并向ADC 发送一个新的启动脉冲,以转换新选择的通道组。/ p$ D: b8 j$ H: k: T 0 ]0 g. L( E, r 7 h2 M1 K& }0 ]& t" T. W( O 3.通道转换标志* b6 j$ { {/ ]/ I ' F. ^: i% F1 ^: Y, I 规则通道组由多达16个转换组成。规则通道及其在转换序列中的顺序在ADC寄存器中选择。规则通道组中的转换总数必须写入ADC SQR1寄存器的L[3:0]位中。! b/ `2 A$ s$ Y% w/ ] 注入通道组由最多4个转换组成。注入通道及其在转换序列中的顺序必须在ADC JSQR寄存器中选择。注入组中的转换总数必须写入ADC JSQR寄存器的L[1:0]位中。 & L0 x' g9 ?" A3 R7 f% `( l 规则通道组:从名字来理解,规则通道就是一种规规矩矩的通道,类似于正常执行的程序。通常我们使用的都是这个通道。注入通道组:从名字来理解,注入即为插入,是一种不安分的通道,类似于中断。当程序正常往下执行时,中断可以打断程序的执行。同样如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程。 ; P% H* j0 c: w2 w1 ^ C 4.触发源. B- {: s% t4 K ) D4 o# G: d' |- T0 z0 _* V 选择好输入通道,设置好转换顺序,接下来就可以开始转换。要开启 ADC转换,可以直接设置 ADC 控制寄存器 ADC_CR的 ADEN 位为 1,即使能 ADC。设置ADC_CFGR的EXTSEL[3:0]选择触发规则组转换开始的外部事件,设置ADC_JSQR的JXTSEL[3:0]选择触发注入组转换开始的外部事件。如果使能了外部触发事件,可以设置 ADC 控制寄存器ADC_CFGR的EXTEN[1:0]:规则通道的外部触发启用和极性选择,ADC_JSQR的JEXTEN[1:0]注入通道的外部触发启用和极性选择,,可以有 4 种状态,分别是:禁止触发检测、上升沿检测、下降沿检测以及上升沿和下降沿均检测。 5.时钟% y3 f; N! [' D/ L 2 c# T$ ~+ }6 A- L9 ^" _" M9 d 三个ADC的输入时钟相同,可以在两个不同的时钟源之间选择。ADC时钟来自系统时钟或PLLSAI1输出(A)。它可以达到80兆赫,并且可以通过以下预分频器值进行划分:1、2、4、6、8、10、12、16、32、64128或256,通过配置ADC1_CCR寄存器。它与AHB时钟不同步。或者,ADC时钟可由ADC总线接口的AHB时钟除以可编程系数(1、2或4)。此可编程系数是使用ADC1_CCR中的CKMODE位字段配置的。如果编程因子为“1”,则AHB预分频器必须设置为“1”。 ) a, }: y6 f- I1 r8 C
h+ y% N) \9 k7 R ADC时钟可以是特定的时钟源。 6 I7 z* D1 l3 x4 Z% e! |2 E8 J 时钟源: " m3 i( l6 R+ F1 \" r" E1 f –系统时钟 –PLLSAI1(单ADC实现)要选择此方案,必须重置ADCX_CCR寄存器的位CKMODE[1:0]。2 e% B4 a7 q3 N( B; j3 p 8 [; z5 k* e; l) Z& @- v( P
PRESC[3:0]: ADC预分频 时钟对于所有的ADC来说都是通用的。0000:输入ADC时钟不分频,0001:输入ADC时钟除以2,0010:输入ADC时钟除以4,0011:输入ADC时钟除以6,0100:输入ADC时钟除以8,0101:输入ADC时钟除以10,0110:输入ADC时钟除以12,0111:输入ADC时钟除以16,1000:输入ADC时钟除以32,1001:输入ADC时钟除以64,1010:输入ADC时钟除以128,1011:输入ADC时钟除以256,其他:保留* c4 h$ p: O) w+ Z- N# } ADC预分频器仅当CKMODE[1:0]=0b00时才应用该值' B& Q- O. U( Z- e6 D CKMODE[1:0]:ADC时钟模式 这些位由软件设置和清除,以定义ADC时钟方案(主ADC和从ADC共用):2 o9 A' q7 t( `$ i4 r8 L 00:ck_adcx(x=123)(异步时钟模式)。 01:HCLK/1(同步时钟模式)。只有当AHB时钟预分频器设置为1(RCC寄存器中的hpre[3:0]=0xxx)并且系统时钟有50%的占空比时,才能启用此配置。; U' H; f3 Y; J 10:HCLK/2(同步时钟模式)- A) \2 A, N: b 11:HCLK/4(同步时钟模式) ! Z8 x! ]- Y' b% T3 c, S PLLSAI1 configuration register (RCC_PLLSAI1CFGR) 2 j3 S. i4 k' U5 Q: Y; h: g
# x/ r- n- C4 x4 h( m' e PPLADC1CLK。此输出可以选择为ADC时钟。这些位只能在PLLSAI1被禁用时写入。PLLADC1CLK输出时钟频率=VCOSAI1频率/PLLSAI1R与PLLSAI1R=2, 4, 6,或8。 00 LLSAI1R=2,01 LLSAI1R=4,10:PLLSAI1R=6,11:PLLSAI1R=8, U5 b0 U3 A$ |9 [& M& Y# z, {* e. `7 U$ L* f% R; a 位24 PLLSAI1REN LLSAI1 PLLADC1CLK输出启用* M6 s* Z0 U: Q6 M% d 通过软件设置和重置以启用PLLSAI1的PLLADC1CLK输出(用作ADC时钟)。当不使用PLLSAI1的PLLADC1CLK输出时,PLLSAI1REN的值应为0。 / N" q: o# ]% S% b! R9 l 0 LLADC1CLK输出禁用,1 LLADC1CLK输出启用+ z9 N" j& a- }2 N ADC时钟还可由ADC总线接口的AHB时钟可编程系数(1、2或4)得出。在此模式下,可根据位CKMODE[1:0])选择可编程系数(/1、2或4)。要选择此方案,ADCX UCR寄存器的位CKMODE[1:0]必须与“00”不同。注:对于选项2,只有当AHB预分频器设置为1(RCC_CFGR寄存器中的hpre[3:0]=0xxx)时,才能使用1的预定标系数(ckmode[1:0]=01)。选项1)具有达到最大ADC时钟频率的优势,无论已选择AHB时钟方案。ADC时钟最终可除以以下比率:1、2、4、6、8、12、16、32、64、128、256;使用配置有位预分频器ADCx_CCR寄存器。不要让ADC时钟超过14MHz,否则可能不准。# E) o- b5 i# q: C' ? 2 }% G/ t$ v7 f$ @% K7 E 6.数据寄存器 4 v6 v$ f% r+ f+ p) {- i# a0 @ ADC 转换后的数据根据转换组的不同,规则组的数据放在 ADC_DR 寄存器内,注入组的数据放在 JDRx 内。 * _3 C# ~( s( x1 X+ X1 y) c9 R( j! { 7 M* x1 z2 M8 Z; s 位31:16保留,必须保持在复位值。+ k, m& k$ I6 j 位15:0 RData[15:0]:规则数据转换 这些位是只读的。它们包含上次转换的规则通道的转换结果。数据左对齐或右对齐。STM32的ADC 是 12 位转换精度,而数据寄存器是 16 位,所以 ADC在存放数据的时候就有左对齐和右对齐区分。如果是左对齐,AD 转换完成数据存放在 ADC_DR 寄存器的[4:15]位内;如果是右对齐,则存放在 ADC_DR 寄存器的[0:11]位内。具体选择何种存放方式,需通过 ADC_CR2 的 11 位 ALIGN 设置。0 u, V+ ]# B4 m- ]4 {. W6 J1 ] " H6 F2 m, b+ X 在规则组中,含有 16 路通道,对应着存放规则数据的寄存器只有 1 个,如果使用多通道转换,那么转换后的数据就全部挤在 ADC_DR 寄存器内,前一个时间点转换的通道数据,就会被下一个时间点的另外一个通道转换的数据覆盖掉,所以当通道转换完成后就应该把数据取走,或者开启 DMA 模式,把数据传输到内存里面,不然就会造成数据的覆盖。 最常用的做法就是开启 DMA 传输。如果没有使用 DMA 传输,我们一般通过 ADC 状态寄存器 ADC_SR 获取当前 ADC 转换的进度状态,进而进行程序控制。* X" W: c% d( ?, I ; w2 U1 n$ M- v* {% h 而在注入组中,最多含有 4 路通道,对应着存放注入数据的寄存器正好有 4个,不会跟规则寄存器那样产生数据覆盖的问题。# m, \% O. y' S6 Z! f8 e6 f 1 u0 v+ x4 P3 e# ]) ~ 7.ADC中断! s+ G7 B/ _6 k4 r ADC可生成中断:在ADC通电后,当ADC准备就绪时(标记ADRDY),规则组转换结束时(标志EOC),在规则组转换序列结束时(标志EOS),注入组转换结束时(Flag Jeoc),注入组转换序列结束时(Flag Jeos),发生模拟看门狗检测时(标记AWD1、AWD2和AWD3),当采样阶段结束时(标志EOSMP),发生数据溢出时(标志OVR),当注入的序列上下文队列溢出时(标记JQOVF)
通道采样时间% X s* J" v' @3 ] 7 e5 y8 r+ E& l5 @ 每个通道可以用不同的采样时间进行采样,采样时间可使用ADC_SMPR1和ADC寄存器中的SMP[2:0]位进行编程。因此可以选择 在以下采样时间值中:) C! s' c6 M6 q4 L; S. p* h •SMP=000:2.5 ADC时钟周期+ g0 W! S$ f- W# k1 s: T# \ •SMP=001:6.5 ADC时钟周期$ f# I. n! n% R/ X: p& _: x •SMP=010:12.5 ADC时钟周期 " {! G( U3 I, k1 C •SMP=011:24.5 ADC时钟周期 •SMP=100:47.5 ADC时钟周期0 E" ]7 L( {) e6 c/ }7 ` •SMP=101:92.5 ADC时钟周期3 \2 I R. Z$ O/ e3 Z •SMP=110:247.5 ADC时钟周期/ f5 W { U" S/ X •SMP=111:640.5 ADC时钟周期8 b. M# s+ ^/ P$ E# E0 W ADC 要完成对输入电压的采样需要若干个 ADC_CLK 周期,计算公式:5 ~ W* Z% O; p# L/ S* \ TCONV = 采样时间 + 12.5 (ADC 周期)5 c5 u% l& I- s) Y 例子: 当fadc_clk=80 MHz且采样时间为2.5 ADC时钟周期时:tconv=(2.5+12.5)ADC时钟周期=15 ADC时钟周期,T=1/f,15*(1/80M)=187.5 ns(对于快速通道) ; d; U* G9 F% J& g2 d ADC采样数值与实际电压值转换 STM32的ADC是12位逐次逼近型的模拟数字转换器,也就是说ADC模块读到的数据是12位的数据。。二进制的12位可表示0-4095个数,也就是说转换器通过采集转换所得到的最大值是4095,111111111111 = 4095,0v-3.3v平均分成4096份。给出任意X坐标值,求Y值 / z3 @7 K! a: A$ g3 F
2 R, b$ Q: S( e 2 x n; e! e# H5 Y DMA(Direct Memory Access,直接内存存取) ,用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。DMA是直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU任何干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。9 S6 M% Y! H& r8 N4 Q2 g- Y0 U# X |
STM32L4R9 QuadSPI Flash通讯速率优化解析 32位总线的DMA传输适配核心方案
【STEVAL-STWINKT1B评测】运行Datalog固件并记录运行时间
【STEVAL-STWINKT1B评测】数字麦/模拟麦对比测试+音频配套上位机软件开发
【板卡评测】STEVAL-STWINKT1B读取 ACC/GYRO/MAG 实时数据
小白也能明白的STM32的低功耗与唤醒机制
【STM32入门学习路径指南】(四步走)
STM32和Arduino对比,谁更耐打?
STM32系统中2种数据掉电保护的方法
STM32 LL为什么比HAL高效?
STM32小白入门指南:从基础到OTA实现方案
微信公众号
手机版