你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32U5 ADC 自校准不成功的问题分析

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:21
01引言
9 O0 D$ Q( [% Q& M) Z% V9 Y很多 STM32 系列中的 ADC 都带有自校准的功能。它提供了一个自动校准的过程,用于驱动包括 ADC 上电/掉电序列在内的所有校准动作。在这个过程中,ADC 计算出一个校准因子,并在内部应用到此 ADC 模块,直到下一次 ADC 掉电。在执行任何 ADC 操作之前必须校准,以消除芯片之间 ADC 结果的偏差。- E7 Y: m9 x% i/ V6 a/ r

! b) B8 A7 L* z& i/ v  F4 D02问题
( O9 [; {0 r/ R* q' n2.1. 问题详情
5 V6 P6 Y. i) y' _客户使用 STM32U575ZIT6Q 验证 ADC4 时,使用 STM32CubeMX 配置后生成工程项目。因为使用 ADC 进行采样转换前,必须要做 ADC 的自校准。于是在 main 函数中加入自校准代码,如图 1 所示。
% D! U# h% e, `& A: |/ Q/ y3 f: V  a
7 S+ R2 ~9 m5 S( h
8.jpg
' M% f- C' r/ z9 u& W0 V
图1.代码:ADC 自校准
; Y$ Y- l0 I4 b) q: T( `; W
+ k, b% e0 a4 |" C' G4 u; _
然而,在运行代码的情况下,发现 PC 指针最后跑到这个 Calibration Error 的Error_Handler()里。也就是说,执行自校准失败了!
0 n: I0 s$ Q  ~3 N+ n1 s; J5 r) ]; Q& p$ D& x; |: c6 g
再检查进入 Error_Handler()发生的问题,发现在执行HAL_ADCEx_Calibration_Start()时陷在了下面这个 Loop 当中,如图 2 所示。
7 f  o, D3 z! ~+ U" `% s
% y9 k! y- q% k$ I3 j
7.jpg
( b7 T; H. C+ D, S$ W' j
图2.代码:等待 ADC 自校准完成
3 s* G- D4 }! q

6 n- g' C4 |/ p, G0 n  @! }也就是说,ADCAL 位被置 1 后,始终没有被硬件清 0,代表自校准始终不成功。8 f1 F8 ?  X, D; w3 A* r
# x3 u/ g8 \1 @: N! }
2.2. 问题分析) D+ |3 T& Y/ u4 |
查看 STM32U5 的参考手册 RM0456 中关于自校准的描述。考虑到校准没有成功,那么应该看看是不是自校准需要哪些条件,而这些条件并没有成立。. Q1 Z4 x. O  @+ W9 b
于是,在 ADC 章节中的 Calibration 小节找到了这么一段话,如图 3 所示。
; |7 B& k/ W6 U
+ }- r* [1 R1 [# W, H. Z
6.jpg

: R' Q5 d' `) C% `6 s+ s
图3.ADC 自校准要求条件

0 T" H5 W" g7 X8 b4 b
5 p' H& c" O, U3 {" M+ j" t  g
也就是说,在初始化自校准之前,需要保证 3 个条件:
# f) Q) T+ W/ Y$ Y3 t2 \1) ADC 的电压调整器已经使能并正常工作(ADVREGEN = 1 且 LDORDY =1)2 }  L0 B# e) g  n5 Q. W" T
2) ADC 没有打开(ADEN=0)
- X) K0 m2 J$ p& S3) 自动掉电模式没有使能(AUTOFF = 0)
3 X4 p& ^" p3 S2 T& [+ i- R2 w- r/ X* ?0 r
回到刚才等待 ADC 自校准完成的代码,当指针停留到这边时,在线调试检查各个标志位情况,发现 ADVREGEN=1,ADEN=0,AUTOFF=0,LDORDY=0。所以,可以肯定的是就是 LDORDY 不为 1,也就是说 ADC 的电压调整器还没有准备好,导致了自校准无法成功并退出。 $ g  ^! S0 i' d4 K: G6 i) [

6 A, b1 q! {+ [* I在 STM32U5 中,引入了一个新的 ADC 特性,叫 ADC 电压调整器(ADC voltageregulator)。在使用 ADC 之前,这个电压调整器必须被使能并且能够稳定工作。可以通过将 ADC_CR 寄存器中的 ADVREGEN 位置 1 来使能它,然后必须要等这个电压调整器的启动时间之后,才可以正常启动自校准或者使用 ADC。这个 LDO 有没有准备好,可以通过 ADC_ISR 寄存器中的 LDORDY 这个位来判断。LDORDY=1 才代表了 LDO 已经准备好了。 & j* G7 I( p( y" E
% A' J1 T7 y. V0 z' v
回到客户的问题,可以知道即使 ADVREGEN 置 1 了,LDORDY 始终没有置起来,电压调整器没有启动工作,难道是 ADC 的这个电压调整器坏掉了?
- G. G7 a2 O3 V& C( m. Q1 A2 u; x% ]/ u6 w8 b4 e
别急,想到电源的问题,还不能忘了参考手册的另一个章节 :电源控制 PWR。翻到PWR 这一章,先要考虑到,与 ADC 相关的电源为 VDDA,所以要重点查看 VDDA 的内容。找到 Independent analog peripherals supply 这一小节,可以看以下关键的句子,如图 4。
# s- B6 H& n/ T2 f1 ?
# v) B4 l. X! H' I* U8 R8 [4 o/ u* n
5.jpg

: _  h3 h2 F) }# A+ m' t6 q
图4.独立的模拟外设供电
! O6 v* g- L2 f) i

: C+ U5 e/ t+ _  n7 H) I从图中黄色高亮的文字,我们可以了解到,STM32U5 的 VDDA 在控制上还跟其他系列不一样,它有一个开关来选择是否隔离。芯片复位后,VDDA 提供的 ADC 和模拟开关控制在逻辑和电气上是隔离的,因此不可用。一旦 VDDA 电源存在,就必须在使用模拟外设之前,通过在 PWR_SVMCR 寄存器中将 ASV 置位来消除隔离。也就是说,要想使用ADC,必须先将 ASV 置位来消除隔离。
; b+ c7 x: o; h" O: d
3 W; Q2 L/ p$ l1 O在 PWR_SVMCR 寄存器的解释中,也可以看到 ASV 位的描述中要求将此位强制置 1才可以使用模拟外设,如图 5。
- O7 L2 u# P3 t1 o5 D6 t4 r, x3 o: }
! l" N, I+ J2 d& e
4.jpg

5 h: P% }4 I' m" |8 r9 N
图5.ASV 位描述

  M" L/ d: `( W* }% ~/ Z
5 b1 O& l/ `; [  l- p# j* S
ASV 的配置是没有在 STM32CubeMX 中进行配置的,所以需要在后期添加。所以,很可能就是因为没有将 ASV 置位以使能 VDDA,导致 ADC 外设被隔离,并没有得到供电,所以 ADC 的电压调整器不可能正常工作,LDORDY 也不可能为 1。
( w( Q8 d0 Y% c9 i* R+ j+ c( W; J9 t2 t
+ R2 j+ W3 g! q- u8 f$ D0 C
03问题解决( ?" i: X( r8 |
在工程项目中搜索 ASV,可以找到两个 API,如图 6。) ?5 T: u& m6 W: t, l$ x; j

1 Y$ h0 H) S4 n3 W/ w0 A
3.jpg
% Z! V" P5 C) J3 T; w& x
图6.VDDA 使能或禁用 API
' G! S2 Y1 @8 o$ c. J& Z" ~

( U4 d( L& F5 L( `也就是说,我们需要先将 HAL_PWREx_EnableVddA()添加到代码中。因为其属于MSP 硬件配置,所以将其加到 HAL_MspInit()函数,如图 7 所示。3 O1 O" B7 k' ]

9 W7 m5 I. r7 A
2.jpg
. n# ]7 K2 B( R; n7 [. A( e" f8 H
图7.修改过的 HAL_MspInit()函数

: ~% f+ l* E6 F4 h  v. w

- U. R" h- Z  I) E
; L" S" [" P+ D  g: A
再重新编译,然后执行指令代码,就可以看到 ADC 的自校准可以正常完成,PC 指针已经可以正常跑到自校准后面的代码了。2 g" [# p! ]+ R/ o5 W7 _
# p$ c/ }9 Y' R" u
04小结# Y( ]0 G( {# n% x
在 STM32U5 中,为了更好地控制功耗,ADC 中加入电压调整器和 VDDA 隔离功能。这与以往的 STM32 有所不同,需要注意一下。使用 ADC 等模拟外设前,需要注意将PWR_SVMCR 寄存器中将 ASV 置位来消除隔离。
7 Y7 k! c: L& D; s: L# L! e9 O7 ~  x* f  Z
其实不仅仅是 VDDA 可以隔离,VDDIO2 也是可以的,通过 PWR_SVMCR 寄存器的IO2SV 位进行控制。
! z) Y( i9 K, o* U  ^8 b* ]1 c  K; U# V+ M9 l' ^2 k
如果仔细看过 STM32U5 的 ADC 例程,可以看到 HAL_MspInit()的内容是这么写的,如图 8 所示。
0 H' V% f: R# k8 c3 n& b( }+ G8 V
5 X# H  v0 \5 J2 U: g' p
1.jpg
. o6 z( o$ E. w: L5 {- T8 Q# J, C2 d0 L
图8.例程的 HAL_MspInit()函数

6 S1 b# q2 u; w; I# J( o6 S% X

. \6 Q$ [, {/ g9 H" C1 Q+ C; x. u9 U$ L, _1 Q% i- P1 x
可以看到,在 MSP 初始化里,不仅使能了 VDDA,还使能了 VDDIO2。所以要使用VDDIO2 相关 I/O 的,也需要注意一下。
  {: w* l7 ?: I! C& n
7 i3 B8 M/ {4 L% x2 R
7 J! m" l9 n6 `7 r
转载自: STM32单片机( Q( q6 D+ h0 \
如有侵权请联系删除9 B1 K. F/ U8 D$ O
3 {/ h# J3 P/ ^0 J! v, \& ^# L
; U- \8 T4 r7 ~5 q% c
/ \% b& T2 D- @( @) ^6 C* Y
收藏 评论0 发布时间:2023-12-11 14:21

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版