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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:21
01引言
- d2 G9 B& L. p9 D6 j很多 STM32 系列中的 ADC 都带有自校准的功能。它提供了一个自动校准的过程,用于驱动包括 ADC 上电/掉电序列在内的所有校准动作。在这个过程中,ADC 计算出一个校准因子,并在内部应用到此 ADC 模块,直到下一次 ADC 掉电。在执行任何 ADC 操作之前必须校准,以消除芯片之间 ADC 结果的偏差。7 a% Q: _) V- X" I8 Y5 B% w5 w
, W8 B( Q4 L6 j/ z! r* ^8 l3 B. J
02问题
2 T: h7 _. d3 F5 K. E2.1. 问题详情
7 t2 V: Y0 K5 f! a( r- `客户使用 STM32U575ZIT6Q 验证 ADC4 时,使用 STM32CubeMX 配置后生成工程项目。因为使用 ADC 进行采样转换前,必须要做 ADC 的自校准。于是在 main 函数中加入自校准代码,如图 1 所示。& B# X/ U7 l$ q; a) j; @
2 Y* ?/ V; b5 F0 O% z) U, O
8.jpg

% |5 f3 D1 T1 g8 H- R9 l
图1.代码:ADC 自校准

& c6 r) O' E- G7 v

# l2 o4 A4 _) @4 v然而,在运行代码的情况下,发现 PC 指针最后跑到这个 Calibration Error 的Error_Handler()里。也就是说,执行自校准失败了! : s; ^6 {4 g" [0 Z8 {( b/ {" F
4 A/ Z$ b. |" r9 @% h+ z" ]
再检查进入 Error_Handler()发生的问题,发现在执行HAL_ADCEx_Calibration_Start()时陷在了下面这个 Loop 当中,如图 2 所示。
$ M( |: P# P' e" z# K
2 N* }$ N- T& j2 D
7.jpg

: f, z! Z' t7 X2 G3 u3 v1 z
图2.代码:等待 ADC 自校准完成
- Y* r' ^5 K6 g% A& n  M4 x

- Z9 w+ V0 d+ d9 `. m+ V6 x也就是说,ADCAL 位被置 1 后,始终没有被硬件清 0,代表自校准始终不成功。4 G" i* @* o8 f( j9 x# b

- o% n. B; l( Z) S' y2.2. 问题分析. b4 r0 j$ }8 d% b  I+ Z: A" l
查看 STM32U5 的参考手册 RM0456 中关于自校准的描述。考虑到校准没有成功,那么应该看看是不是自校准需要哪些条件,而这些条件并没有成立。# C7 M' W/ ]8 N+ m
于是,在 ADC 章节中的 Calibration 小节找到了这么一段话,如图 3 所示。
7 |  @! x' p" O
* D: Q8 G' {  J: {5 t0 @
6.jpg
/ \4 R) i4 W: M& Y' s
图3.ADC 自校准要求条件

8 ^4 |: V3 I5 F
( L! H9 C" |/ d3 o) w' ?( x: u
也就是说,在初始化自校准之前,需要保证 3 个条件:
, G$ f" z6 y3 c" [8 l/ C9 ?1) ADC 的电压调整器已经使能并正常工作(ADVREGEN = 1 且 LDORDY =1)
& D: C% B$ R1 {. U1 t& _2) ADC 没有打开(ADEN=0)9 t9 |4 h2 U% k5 W
3) 自动掉电模式没有使能(AUTOFF = 0)
" ?9 D; r0 \3 k* O9 {; \; R9 p' C# D8 i0 y
回到刚才等待 ADC 自校准完成的代码,当指针停留到这边时,在线调试检查各个标志位情况,发现 ADVREGEN=1,ADEN=0,AUTOFF=0,LDORDY=0。所以,可以肯定的是就是 LDORDY 不为 1,也就是说 ADC 的电压调整器还没有准备好,导致了自校准无法成功并退出。 $ N$ G' G& U: e2 F* b9 `
$ u1 G+ _" v2 o0 \4 _
在 STM32U5 中,引入了一个新的 ADC 特性,叫 ADC 电压调整器(ADC voltageregulator)。在使用 ADC 之前,这个电压调整器必须被使能并且能够稳定工作。可以通过将 ADC_CR 寄存器中的 ADVREGEN 位置 1 来使能它,然后必须要等这个电压调整器的启动时间之后,才可以正常启动自校准或者使用 ADC。这个 LDO 有没有准备好,可以通过 ADC_ISR 寄存器中的 LDORDY 这个位来判断。LDORDY=1 才代表了 LDO 已经准备好了。 % m2 C6 _9 Y! T
5 H9 ~+ V& F. h+ j* ]
回到客户的问题,可以知道即使 ADVREGEN 置 1 了,LDORDY 始终没有置起来,电压调整器没有启动工作,难道是 ADC 的这个电压调整器坏掉了? + [, r" ]& C" d% T3 d( e0 U

9 q( d) O3 j$ }- }3 F别急,想到电源的问题,还不能忘了参考手册的另一个章节 :电源控制 PWR。翻到PWR 这一章,先要考虑到,与 ADC 相关的电源为 VDDA,所以要重点查看 VDDA 的内容。找到 Independent analog peripherals supply 这一小节,可以看以下关键的句子,如图 4。
4 R' V: s# s3 h( j0 L$ Y
4 W9 [, a( r* U' i: S
5.jpg
' G: u% R8 F  P) w
图4.独立的模拟外设供电
+ V9 a& G9 L8 t! w& a

* m" f  G( O& ]" D& `% r9 N8 L8 W0 V从图中黄色高亮的文字,我们可以了解到,STM32U5 的 VDDA 在控制上还跟其他系列不一样,它有一个开关来选择是否隔离。芯片复位后,VDDA 提供的 ADC 和模拟开关控制在逻辑和电气上是隔离的,因此不可用。一旦 VDDA 电源存在,就必须在使用模拟外设之前,通过在 PWR_SVMCR 寄存器中将 ASV 置位来消除隔离。也就是说,要想使用ADC,必须先将 ASV 置位来消除隔离。 2 p1 t' H+ S6 n. N6 X# L6 X9 e* d

" G3 b: A2 s( S在 PWR_SVMCR 寄存器的解释中,也可以看到 ASV 位的描述中要求将此位强制置 1才可以使用模拟外设,如图 5。0 N+ W, |& I0 E. m1 O
9 H4 [! ]: z, z
4.jpg

6 ^* {7 a1 Y1 L9 m1 E0 R, {$ V
图5.ASV 位描述

2 {0 X4 h6 {" }9 j) Z

4 t  e0 A# X" w6 D7 H% r8 @! IASV 的配置是没有在 STM32CubeMX 中进行配置的,所以需要在后期添加。所以,很可能就是因为没有将 ASV 置位以使能 VDDA,导致 ADC 外设被隔离,并没有得到供电,所以 ADC 的电压调整器不可能正常工作,LDORDY 也不可能为 1。1 w6 M5 J2 J, m. q9 ?

- P+ x+ l) D( u) ~5 z/ s03问题解决
4 c7 x/ N8 N/ w9 @( F: t3 ?0 H; t, y在工程项目中搜索 ASV,可以找到两个 API,如图 6。8 }) J7 V: [* U( m7 d, ]3 P* Q

$ Y# E" G0 ?) `0 n% p# A
3.jpg
, U8 d7 L. _) P+ k
图6.VDDA 使能或禁用 API

- t5 r8 c" j" k. l2 E6 ?" i4 u+ }- C

: ]0 G! X8 m, }& z5 ]5 n也就是说,我们需要先将 HAL_PWREx_EnableVddA()添加到代码中。因为其属于MSP 硬件配置,所以将其加到 HAL_MspInit()函数,如图 7 所示。) O% Y" A; L6 ^* E

2 |' K9 V! W9 |0 B0 i
2.jpg
! n2 _2 I' S# S# h' f) e
图7.修改过的 HAL_MspInit()函数

, ^1 h0 W  t" O

" c$ _# b' r8 L0 V; Y, {

% V0 \7 f# I: A/ q再重新编译,然后执行指令代码,就可以看到 ADC 的自校准可以正常完成,PC 指针已经可以正常跑到自校准后面的代码了。; R7 E- Y9 J1 T$ |$ h1 }6 c
+ B% Y% T2 T9 X4 c# G; Z( w. d
04小结
  ~" [! v+ S: c3 F+ n' X3 ]9 w在 STM32U5 中,为了更好地控制功耗,ADC 中加入电压调整器和 VDDA 隔离功能。这与以往的 STM32 有所不同,需要注意一下。使用 ADC 等模拟外设前,需要注意将PWR_SVMCR 寄存器中将 ASV 置位来消除隔离。 9 A' a) K* `: ]- V, s) i% i
" F+ S' k% F0 L  M! V8 a
其实不仅仅是 VDDA 可以隔离,VDDIO2 也是可以的,通过 PWR_SVMCR 寄存器的IO2SV 位进行控制。' `2 m" n# S/ r. I& |4 _. ~( o) Y) M
- q0 p+ }+ C8 Z) J
如果仔细看过 STM32U5 的 ADC 例程,可以看到 HAL_MspInit()的内容是这么写的,如图 8 所示。9 G1 V6 E$ A; t; P

8 T: M: U* h) ~% X0 J' u2 x+ U7 F
1.jpg

* J7 l0 u* p( n5 M
图8.例程的 HAL_MspInit()函数

* R' a) [. U' `! y9 w3 N5 [
1 }; D  Q1 @: U2 d0 F# k, o! [3 c9 s, b

, j8 `1 }% ?7 W- i. l) y
可以看到,在 MSP 初始化里,不仅使能了 VDDA,还使能了 VDDIO2。所以要使用VDDIO2 相关 I/O 的,也需要注意一下。9 W) H- a, A1 W: [+ z0 Q2 _* A

& V8 g1 T  O& L/ S
& H6 h! j1 u9 C1 `
转载自: STM32单片机
' V& I5 U8 h6 o如有侵权请联系删除  S1 w! I$ D1 V, I8 `

0 R" ?' T! [- y0 `
1 U5 V4 k) J- v; j
6 u# j4 @0 [4 I; k
赞 收藏 评论0 发布时间:2023-12-11 14:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版