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

【经验分享】验证 STM32F401 在 STOP 模式下的电流

[复制链接]
STMCU小助手 发布时间:2022-3-5 09:44
问题:# g" a0 w- H. N; Y: ?
该问题由某客户提出,发生在 STM32F401CEY6 401CEY6 401CEY6 器件上。据其工程师讲述:在程序中,在进入 STOP 模式之前他已经将 STM32F401 的 I/O 口做完处理了,但是电流仍然比数据手册写的数值还要大很多,不知道是在哪里消耗了电流。希望能帮他验证一下。& `: X) E4 c7 C  r' R- y# q
. t  z8 j0 G3 l/ M
调研:& Z. B# `$ M; M# b4 t% G) m
我们先来看一下 STM32F401 的数据手册中,对其在 STOP 模式下工作的电流的参数:
5 i7 @: W8 m. N' g- [3 R4 j
! ?2 m5 x1 q* a# H7 k! d 1@1I2[1{R[$~B6{MO08@A}8.png . [/ K  W# w- ~$ D3 \* T* h! O
/ c6 {0 z7 z' r) u7 d  E
按客户的要求,我们主要是验证在 STOP 模式下,调压器在低功耗模式下的电流,也就是表格中典型电流为 42uA 的那个值。3 ^/ m% ~( L8 [" S. x; [
我们使用 STM32F401 的 Discovery 板进行验证,因为在 Discovery 板上只需要把 Idd 的那个 JP2 的跳线帽拿掉接上电流表就可以测试电流了,当然,我们必须要检查一下,这个电流供进来给 MCU 作为VDD 时,还可能连接什么电路会导致电流消耗的,检查了一遍,主要是要注意 BOOT0 以及 BOOT1脚。
7 S0 L- Y! K; s/ g
5 E) ]7 U4 v" f% |; }: R- Z$ W. q0 u LP_)IU6}S`I{1BSRZ_$()UI.png 6 L- d. E' k5 L0 A+ d$ \( k8 U
! ]1 q6 ~" i: N$ _- h4 N
由于运行用户代码,所以 BOOT0 和 BOOT1 都将接到低电平上,所以电路上要确保 SB19 和 SB20 短路,但是我们可以看到,BOOT1 上面从 VDD 到 R30 到 R31 再到 GND,将会有一个电流产生,所以必须要把 R30 取下来。BOOT0 由于本身 R29 就没有接,所以倒是没有关系。
+ `: }$ w5 q$ w( V, G( D好,那现在开始验证电流,我们使用 32F401CDISCOVERY 的固件库中的 PWR_STOP 的例程来验证。因为不使用 RTC,所以我们将程序中的 RTC 部分删掉:将 stm32f4xx_it.c 中的 voidRTC_WKUP_IRQHandler(void)函数中的内容删除,再将 main.c 中的 static void RTC_Config(void)函数删除,在 int main(void)主函数中也清除掉相关的内容,主函数如下:' ~, O) [" B  ]/ x
  1. int main(void)
    & U5 e* ?7 V7 [2 j7 ?/ N, S) n1 R& b
  2. {: W' z0 [* h- A1 R$ B/ t2 c
  3. /*!< At this stage the microcontroller clock setting is already configured,
    ) {' V( R/ n$ J/ F; U" i
  4. this is done through SystemInit() function which is called from startup, J, Z- K7 E& L$ P/ }
  5. file (startup_stm32f401xx.s) before to branch to application main.# B4 {- L" P; r, K9 @0 D, f
  6. To reconfigure the default setting of SystemInit() function, refer to
    0 O* R0 i4 s  O% Z  I
  7. system_stm32f4xx.c file
    0 j* ^. h- S( L; D7 L0 z, J
  8. */
    3 i* A! p) q1 \) n

  9. " f# p% \" o( F0 x
  10. /* Configure the SysTick to generate an interrupt each 250 ms */
    2 ?8 d4 P  M! l) A" w
  11. SysTick_Configuration();
    ! }0 T. _' u2 K- [0 @  u" E: l
  12. /* Initialize LEDs and User Button mounted on STM32F401C-DISCO board */
    : n* X5 v7 ~( A4 r8 A2 d
  13. STM_EVAL_LEDInit(LED3);3 k2 A4 d: f# H8 l( B! i' F
  14. STM_EVAL_LEDInit(LED6);( g! c$ E  d3 }; I
  15. /* Key button (EXTI_Line0) will be used to wakeup ths system from STOP mode */: g( n# `) J$ v- G* M) x6 z
  16. STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);9 \& ?' I! H8 l& ?; e
  17. while (1)
    % @! t. w& e2 W+ p; y
  18. {( H" O! \) _' ~
  19. /* Insert 5 second delay */# ]# j. P' R) [3 A) C9 Z
  20. Delay(20);4 l: a' c* P1 U) y5 C
  21. /* Turn OFF LED3 */
    + B5 r* @, c' @# o. o4 ^
  22. STM_EVAL_LEDOff(LED3);$ H2 J( j0 e" _* L
  23. /* Enter Stop Mode */
      f) j, _- W" ^8 v3 s1 Y
  24. PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);4 V0 q+ [2 z4 Y4 g2 K
  25. /* Configures system clock after wake-up from STOP: enable HSE, PLL and select% h- Z% P/ g  G& T& X! T
  26. PLL as system clock source (HSE and PLL are disabled in STOP mode) */7 w& l4 ~, n2 J; X$ }6 R- s
  27. SYSCLKConfig_STOP();
    : I: `% k+ Z7 P: j* Y
  28. }
    4 h, |3 H5 H. e% E0 `; q
  29. }
复制代码
& C* j* m# s7 Y5 _
编译,下载测试电流,进入 STOP 模式后电流为 2.23mA 左右。3 x$ _# N$ L" h' E  A: M
大家应该已经发现,此例程在进入 STOP 模式之前,并没有对 I/O 口进行处理,导致很多配置为输入浮空的 I/O 口在受到外界干扰的时候,状态不定,消耗了大量的电流。在实际应用中,在进入 STOP模式前,可以根据实际情况,将 I/O 口设置成模拟输入,输入+上下拉电阻,或者输出固定电平。所以,在这里,我们将我们没用到的 I/O 通通设置为模拟输入,只保留 PA0 作为按键,产生外部中断来将 MCU 从 STOP 模式中唤醒。配置 I/O 口后,为了方便从 STOP 模式唤醒后还能直观地看到 LED灯,我们需要在 stm32f4xx_it.c 的 void EXTI0_IRQHandler(void)函数中加入 LED6 的初始化函数STM_EVAL_LEDInit(LED6),在 main()主函数的 SYSCLKConfig_STOP()之后加上STM_EVAL_LEDInit(LED3)。
& G9 r; D3 s! H9 O& _void EXTI0_IRQHandler(void)如下:' ^* S% l" f* I& I0 g; U; V  u
  1. void EXTI0_IRQHandler(void)+ j" b: x3 W  ]& r2 T4 ]; B/ ?$ a$ x
  2. {
    1 j, w0 `8 F5 i( G  l7 p
  3. if(EXTI_GetITStatus(USER_BUTTON_EXTI_LINE) != RESET)
    6 C. @) J) S' @: @2 h, O  F# ]
  4. {: G0 q; F% s  @( y5 ~9 h0 Z
  5. /* Clear the USER Button EXTI line pending bit */! K& j- h) F+ e
  6. EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);/ ^& C( i& P/ T( a! Q: y4 E
  7. /* Toggle LED6 */
    , R; r! X6 D6 b
  8. STM_EVAL_LEDInit(LED6);
    + `8 S7 P+ `5 ]) ~$ _7 s1 m, ~
  9. STM_EVAL_LEDToggle(LED6);
    * N2 R' f6 w6 s
  10. }
    9 \( @+ z, D6 i. d9 Q7 j
  11. }
复制代码
( j% W- g/ U0 U
Int main(void)中的主循环 while(1)中的内容如下:  L* |! `/ I( v2 C4 H! g( Q1 k
  1. while (1)
    6 z. M3 D- S6 p! o( n' e6 y
  2. {0 n" K# e! o8 Y/ @! H1 V9 O
  3. /* Insert 5 second delay */6 ^$ c; R8 g, Q" S2 z/ X' P
  4. Delay(20);
    " Y6 w2 G4 U+ H0 M1 }5 ^' e! f! ^! U9 s
  5. /* Turn OFF LED3 */
    / q6 J+ o0 p8 N  J) A- ?  e; n
  6. STM_EVAL_LEDOff(LED3);" i; y$ W9 d1 G( @% z

  7. & {1 [" o& q0 l/ l& L: A. {
  8. /* Configure all I/O ports */5 P, |9 }; F" l! F$ Z
  9. GPIO_InitTypeDef GPIO_InitStructure;/ n3 c# d) P# X  X& E
  10. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    8 V; A0 h% ]# U3 J/ z" g
  11. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);: V) ]% n! x5 C& [& o# l; _
  12. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);& w: I: k$ j8 c7 Q' W; x+ E
  13. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);8 s4 z+ M  _, Z9 W
  14. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    3 P7 I: {8 _- F! ^$ ]: m) ~+ c1 J
  15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
    , o) S$ |5 N5 `6 F% U* n' ~0 r6 |! V
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    0 j! I/ C, i5 c. s8 g3 T8 b
  17. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    # Q5 x: W' D+ h" o' K
  18. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      W5 R$ Q+ ~3 c" x8 J3 i
  19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    ) V& J1 C% X+ [' S
  20. GPIO_Init(GPIOB, &GPIO_InitStructure);
    9 L/ D$ R" U( o6 I7 @3 l4 q% H
  21. GPIO_Init(GPIOC, &GPIO_InitStructure);9 h# T, |# z; ?  ]# p" F5 ^
  22. GPIO_Init(GPIOD, &GPIO_InitStructure);; _/ O  i4 n- s: E  O2 d
  23. GPIO_Init(GPIOE, &GPIO_InitStructure);
    ( Q( u2 d( ?1 R& ^* D$ k
  24. GPIO_InitStructure.GPIO_Pin = (~GPIO_Pin_0);
    8 F9 n3 \4 t) [* v- N% ~; I2 ]/ I  E
  25. GPIO_Init(GPIOA, &GPIO_InitStructure);' q" _6 |7 }. C
  26. /* Enter Stop Mode */
    6 m' ~( S1 S! f9 \* Q
  27. PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
    $ d: s7 W- Y# |- d. M
  28. /* Configures system clock after wake-up from STOP: enable HSE, PLL and select" e3 M3 c" W  Z! Z/ z. `
  29. PLL as system clock source (HSE and PLL are disabled in STOP mode) */
    & Y* g, @/ t5 h4 B6 L
  30. SYSCLKConfig_STOP();: A8 v9 y7 n3 |' J% W3 N3 D
  31. STM_EVAL_LEDInit(LED3);% O3 `# K' F" P! I% p
  32. }
复制代码
: q  J" v4 I; ^0 o9 z1 I1 N
编译,下载测试电流,进入 STOP 模式后电流为 155uA 左右。这不对啊,距离我们看到的 42uA 还有很大的差距。客户就是在这里不知道为什么了。5 T) c1 o: ~, k7 \' z; `
我们来继续查找原因,客户跟 32F401CDISCOVERY 板一样,使用了外部 8MHz 晶振,所以当使用HSE 的时候,PH0/PH1 被作为 OSC_IN 和 OSC_OUT。问题来了,当进入 STOP 模式时,HSE RC振荡器被禁止,PH0/PH1 这个时候就不再是 OSC_IN 和 OSC_OUT 了,变成普通的 I/O 口,而且是处理浮空输入状态。所以我们还得需要对这两个引脚的 I/O 配置进行处理。再来修改 main()主函数中的while(1)主循环,加入对 PH0/PH1 的处理,程序如下:9 g% [: [  i* [' [5 K) g4 I- m
  1. while (1)
    ( P- Y) w# W8 C+ w( ^
  2. {
    6 s- e# O. g+ h, N" U& _
  3. /* Insert 5 second delay */; b0 f7 X9 ]8 d+ O) \, A
  4. Delay(20);1 {2 j" L" R* m) z+ t
  5. /* Turn OFF LED3 */# J+ O2 G8 n( P, j
  6. STM_EVAL_LEDOff(LED3);
    + x6 [7 u3 A) H7 s
  7. / t" x% D% }" q( j/ u# B5 I
  8. /* Configure all I/O ports */
    6 y) |2 g# A1 c; y
  9. GPIO_InitTypeDef GPIO_InitStructure;# g2 H8 V3 T2 l
  10. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);/ n: Q6 q- K7 }3 M& ^7 q" ]4 D5 G
  11. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  R" X) [( a9 b: P
  12. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);, g% u1 P/ S; h- j
  13. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);$ {. P8 W/ ]" C8 d: B8 x
  14. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);  {/ N8 S3 R1 m. D+ z
  15. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
      M  ?$ d& T; L8 V- C/ A& }7 v4 @
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
    ' r+ e' m5 f( W2 q7 [' I
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    4 g7 N7 M/ Q3 `( X6 }0 q
  18. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    7 C* j2 L1 J# W4 {# Z. E6 v7 C! V9 l
  19. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;/ c4 V; c0 h. m! }/ {; N; G2 W5 A3 o7 g
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;% m& q" x* P2 N' O1 f5 y5 }
  21. GPIO_Init(GPIOB, &GPIO_InitStructure);) L0 b% ?, c# e
  22. GPIO_Init(GPIOC, &GPIO_InitStructure);
    ; v2 q7 h. q# ^- [1 C
  23. GPIO_Init(GPIOD, &GPIO_InitStructure);
    1 J$ I) L+ e2 D  z9 D1 }% u
  24. GPIO_Init(GPIOE, &GPIO_InitStructure);$ C0 D+ L9 ^  |, e, U& Q! A
  25. GPIO_Init(GPIOH, &GPIO_InitStructure);* ^4 L! u. _+ z$ p  W! D
  26. GPIO_InitStructure.GPIO_Pin = (~GPIO_Pin_0);) A/ J) U3 d" k3 f( @8 D  t! A: p
  27. GPIO_Init(GPIOA, &GPIO_InitStructure);: ^: J4 y, w+ r4 h5 o3 S
  28. /* Enter Stop Mode */
    4 O$ f( ^, G" E4 S6 o
  29. PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);6 A/ J/ q: |, S% G1 Y1 U1 j7 s
  30. /* Configures system clock after wake-up from STOP: enable HSE, PLL and select+ _: k8 q& a) Q9 s
  31. PLL as system clock source (HSE and PLL are disabled in STOP mode) */
    4 d- a+ V/ g4 ^% D/ m; A4 S
  32. SYSCLKConfig_STOP();0 y& \7 ?9 q* f/ O! S
  33. STM_EVAL_LEDInit(LED3);0 Y7 e: n/ u4 c" J0 x
  34. }
复制代码

9 a6 D& `$ T, P编译,下载测试电流,进入 STOP 模式后电流为 38.5uA。已经比我们从表格中看到 42uA 还小了,任务完成。当然,数据手册中 42uA 是在 VDD=3.3V 的情况下数值,而我们的 Discovery 板的 VDD 为3V。6 i0 o, ]" F& B! Q+ ^$ D% I
( b: U! ~& ~4 p0 f
我们还可以再测一下让 Flash 进入掉电模式下的电流,修改 while(1)程序如下:0 n$ D3 {* t/ e6 e/ w, o( f* w
  1. while (1)
    ( }: C$ \) I# A& J6 U3 Z
  2. {. _# z$ Z3 k- D
  3. /* Insert 5 second delay */1 m; I5 M$ G' ~" a3 |: T9 S
  4. Delay(20);
    6 ]8 o3 I* c# ]  a: c! U- Q/ C! c$ P) S
  5. /* Turn OFF LED3 */
    + v& E/ ?7 F3 l) W, ]
  6. STM_EVAL_LEDOff(LED3);
    % ?" L/ k+ V( C$ B( z! z

  7. : _  ], d9 P- b+ S8 C1 T3 b
  8. /* Configure all I/O ports */5 s2 t9 s' N/ Z- ^* h
  9. GPIO_InitTypeDef GPIO_InitStructure;# o& a$ P" Z( O! ?5 V  Q1 D  a
  10. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    + v3 {% a- s+ y$ x
  11. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);0 E! d! D8 p; G. H/ N; q
  12. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    0 a8 Z( V, u* R( \# ?3 G
  13. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    & ?  [. e+ G! L+ c. `
  14. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);# s9 h! u/ {  u
  15. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
    / y5 X$ d" P: {4 ~  ]; I
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;; G  v! {6 H2 b" d' E, b8 s9 `6 u
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;0 V( P0 F1 w8 T+ \+ S7 ?
  18. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    4 W% \2 t  c$ u) `; ^
  19. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;# _1 _' x7 z4 {% y. ?9 a; L
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;# l! E  H6 `/ m8 t* v
  21. GPIO_Init(GPIOB, &GPIO_InitStructure);1 b. q; S0 k  O
  22. GPIO_Init(GPIOC, &GPIO_InitStructure);
    . t, n$ ^: @$ S5 r' Y7 t/ o8 F; x* y
  23. GPIO_Init(GPIOD, &GPIO_InitStructure);
    0 A. i& v$ S! l, T8 v' g
  24. GPIO_Init(GPIOE, &GPIO_InitStructure);
    - ~% D4 n/ Y4 l- [& Y* e
  25. GPIO_Init(GPIOH, &GPIO_InitStructure);
    : k+ y  i9 f+ W% w$ ~) @, e/ A
  26. GPIO_InitStructure.GPIO_Pin = (~GPIO_Pin_0);! _) a# W) J) z3 V* l* \
  27. GPIO_Init(GPIOA, &GPIO_InitStructure);+ w) k, ]  f5 T( d7 ^  s* s
  28. /* Configure flash power down mode */9 |' s" [& F& M, q
  29. PWR_FlashPowerDownCmd(ENABLE);  G! O( J7 M9 O; [* `6 v  Q9 \
  30. /* Enter Stop Mode */
      Y* ^) K! J9 o
  31. PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);% s, ~' y  h7 ~. F' T2 o! R
  32. /* Configures system clock after wake-up from STOP: enable HSE, PLL and select
    8 I3 O; O0 y1 L( u: P* W# [; ]
  33. PLL as system clock source (HSE and PLL are disabled in STOP mode) */+ m& t# P$ q) X, v
  34. SYSCLKConfig_STOP();
    ; U- m# S& J% Q& \
  35. STM_EVAL_LEDInit(LED3);. P1 w' Z$ S1 B: x+ I: C
  36. }
复制代码
0 @( d; q1 s: n1 r! `
编译,下载测试电流,进入 STOP 模式后电流为 10.2uA,与数据手册中的典型值基本一致。
9 @: r# D: Z& ?; q( u- c1 J5 l8 i. u
结论:
3 c; E' B. k1 @; n客户在硬件上使用了 HSE,而在进入 STOP 模式前,只对其他 I/O 进行了处理,漏掉了 HSE 对应的两个I/O 口,导致电流过大。1 N9 b9 P7 k/ q

1 B6 L# g6 l. O2 Q: ^处理:* k. j; D+ |1 ?( F+ f
对 PH0/PH1 进行处理,进入 STOP 模式前配置成模拟输入。
" \; T+ f* Y4 E  @* I4 J" y) `7 a7 l
建议:
9 ^0 _! b: H1 o在进入 STOP 模式之前,一定要根据实际电路情况,细致地对各个 I/O 口进行处理。
( Q0 t0 F7 v) }# W  x2 J+ o& v, S" k- ]- ?

' B3 w4 D+ t: L: l8 s% `' Z3 E0 @8 g4 q& Y
' g5 N" [5 Q' d: D7 s
赞 收藏 评论0 发布时间:2022-3-5 09:44

举报

0个回答

所属标签

相似技术帖

官网相关资源

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