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

【经验分享】STM32G0 stm32g071 关于待机模式和关闭模式的进入和退出(RTC和wakeup pin) HAL库 Standby Mode and

[复制链接]
STMCU小助手 发布时间:2021-11-8 15:49
两天的调试与查阅资料终于明白了HAL库中的低功耗模式的切换和退出。主要还是自己作死选择了STM32G071,本文内容基于NUCLEO-G071RB,CUBEMX版本5.2.0,STM32Cube FW_G0 V1.2.0,MDK 5.27.1.0。
8 p" l1 H; H4 n* \4 }0 q5 Q0 s' s9 @( }- G% A, |
首先配置时钟、UART、RTC和中断。5 N3 c& B, J4 M# B$ l/ v

& M( P; w: l+ k& T% F* C: ]
20190510004029552.png

# s' C/ f; {6 U2 F( R3 Q: T3 J
3 G& J0 _5 `: |; E- M3 S/ C7 DRCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认
0 P3 v4 g, Y: P6 o8 `9 \. ]3 m& q* u* h
20190510004154456.png
) O3 j& I& r+ y% ^3 p
/ [8 F$ M  D$ A# c7 F# \% y
SYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的
, v- ~# i  n; [& t2 e  a( E& M6 t3 s2 d- L8 N6 I# Y
20190510005141588.png
# E, ]/ s% ~# f( }
+ n. g2 A: u* g0 N8 l8 |0 r8 O! y
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)4 x/ E* C+ `% L; V

: Q) w" h4 X3 g& u
20190510005211104.png
# P, l4 Q$ r0 u  l* ^  ]

4 {! J" x6 {$ U8 \设置串口, t% o) K! P5 I+ V- s
7 ]. W5 a! L1 H) t1 i. I
20190510005241164.png
7 w6 q, Q) K$ i$ c4 Z5 N

3 R' U  f& q; T3 v打开中断入口7 e4 ~9 u$ J+ X4 G& k6 i# X/ h
7 _8 J' m. f9 `3 R  p, C. y
2019051000534771.png

* l4 E6 S( T9 V/ o1 b; ~: Q8 z$ {7 y/ o* C. N; F! Y4 w
20190510005358325.png
: m$ j2 p# ~. Q: E& M+ p& v$ ^
; B& |. s- N8 j. |* E$ O
完成设置后点击生成代码创建工程; m9 h; P( o- H

* P8 K6 l: n. z/ p+ y( A3 Z2 Z1.首先喜闻乐见的printf函数
; V6 P3 e1 |6 |7 `( R. I
  1. /* USER CODE BEGIN Includes */9 G6 ]) q& |2 t$ Z+ q+ W
  2. #include "stdio.h"
    ( ^/ `0 U6 x2 A6 w# O) f
  3. /* USER CODE END Includes */, A4 g: s- R# _* k1 W4 b: S

  4. 7 h  o& u9 _3 n7 q2 T
  5. ! ~: {8 M! T) J! L
  6. : O) _# `& j9 N4 k
  7. #ifdef __GNUC__
    : O5 i* Q  ~: I8 J4 h  ]
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf' F  P/ q$ c' w8 C+ `1 n( L0 k6 X, r+ }
  9.      set to 'Yes') calls __io_putchar() */
    3 W1 H$ b! k4 X5 J
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
      _) G! O2 _& t3 a: w: u' H$ G
  11. #else
    - F; t6 c0 h( F* d8 b2 z
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    4 ^6 H0 }! _& d7 w) j
  13. #endif /* __GNUC__ */
    ' ^3 k1 Q3 }! G9 ]: O/ ^+ z- x
  14. PUTCHAR_PROTOTYPE4 y0 x. u# [. p
  15. {: F) _7 z9 ^0 o. s! l
  16.   /* Place your implementation of fputc here */
    8 R. O# Z  ~0 Q+ J+ x/ m
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */: x  W" L, i/ ?$ H! l. f

  18.   Q# }& h, M9 D
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
    & o" T2 T1 d! P2 z5 w) r9 ?
  20.         
    2 {+ z, @0 z% d$ X1 L" F* c
  21.   return ch;5 A/ a" O2 Y& x! V: i+ |
  22. }
复制代码

! e0 `& d* {' y1 g6 y! K; U2.RTC时间获取函数8 ?# {9 Z4 |) Q" f4 I% ]
0 D+ ?! }/ v' ]# O. O
  1. /* USER CODE BEGIN PTD */
      x" r8 j( w! B) A* c4 l5 J- n8 o5 c. {
  2. RTC_DateTypeDef sdatestructureget;* o  [8 g; |: x* S' H2 W4 e
  3. RTC_TimeTypeDef stimestructureget;
    ) G9 P9 S8 f! S( k" i$ f
  4. uint8_t aShowTime[16] = "hh:ms:ss";* K# U5 t/ `. w; n" z. R: w! t6 W
  5. /* USER CODE END PTD *// c1 V8 I$ N! s% g1 j
  6. ; `9 d) P6 Y' H' @) `% I) M  I( v+ b0 n
  7. /* USER CODE BEGIN PD */
    6 c+ ~# h3 k- y- E0 K/ a0 r: }
  8. static void RTC_TimeShow(uint8_t *showtime);
    * |& P8 ?$ i) C, ^. v" I: F5 p2 ?
  9. /* USER CODE END PD */
    8 p8 e% U, h$ M

  10. & I. L7 w0 g" q6 W& i
  11. , Z) s; d) l( s" I  t: g2 t
  12. static void RTC_TimeShow(uint8_t *showtime)
    : t( z; V- T* \
  13. {, U& U& W/ u& ]* D' H2 O
  14. 6 t) X- Z$ [" c# B5 J$ _* d

  15. . ^  k6 H, R, m2 j; B; R! l' F
  16.   /* Get the RTC current Time */
    0 ~5 |8 T" `7 f9 q6 O- Q8 s
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);* t% V" v; Q. h- O$ F( ^2 R' @
  18.   /* Get the RTC current Date */9 a8 \% g# c) E2 N
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);" A8 y, y1 b5 m
  20.   /* Display time Format : hh:mm:ss */
    ( X- T' `6 p9 N% A) v
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
    ) T4 p# ?8 e! q% m* e
  22. }
复制代码

) T3 @8 e( i/ O  h3.standby进入函数: h' x0 l( B# B- ^) U
  1. /* USER CODE BEGIN PD */6 [) B& l( p& d0 R( I# M
  2. void Sys_Enter_Standby(void);
    * H, h; @  _1 ^. _
  3. /* USER CODE END PD */% E; i2 W, j# o8 b. x# k# c6 b( s

  4. 6 i; C- C7 I& v# G) L
  5. void Sys_Enter_Standby(void)  ]& @9 g+ F5 i. K% i5 h9 N
  6. {
    : a0 _* c% J4 B
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry
    : H$ D3 Y" {" h" x0 [7 Q
  8.   - Enable wakeup4 V  P* A2 f# p% s7 q* O. v% M: M  s
  9.   - Clear wake up pin flag depending in edge detection & pin level.
    0 \1 L2 x/ G! i  N% [* J2 M
  10.   - Enter the Standby mode.# b5 P% {. Z) k5 t8 P
  11.   */
    ' ?/ j0 s) w; d# u2 C
  12. - k& k1 s" |# X* ]
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */
    ' D; d- j- n( ?6 C. O* b3 V$ k
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发8 b; |0 O" x' d$ F6 Y: N
  15.   HAL_PWREx_EnableInternalWakeUpLine();
    9 G/ p' Z8 L4 c7 z
  16.   /* Clear all related wakeup flags*/" o, ]6 d! B& t3 k
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    0 y; C) q) ?, P6 m

  18.   C- I* e8 r6 ?: |  b9 B; k; E
  19.   /* Enter the Standby mode */
    ' r2 n- `& Y. n
  20.   //HAL_PWR_EnterSTANDBYMode();# b& F4 u! |# X) i& [7 L
  21.         printf("enter Shutdown Mode!");. X2 Q" |% @4 y6 v4 a1 t" B8 q
  22.         HAL_PWREx_EnterSHUTDOWNMode();0 Z8 n/ \1 Q% R5 B3 i7 ?* U: B
  23. ! |3 T0 ~0 J+ M( q% V5 H
  24.   /* This code will never be reached! */3 F: P6 [- e/ J, D
  25. }
复制代码

- m9 I3 N. n  U2 `, @4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位). }, x/ [6 g( R  p
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)( R4 n) n( x8 }. R/ f+ b: o
  2. {- v  f) o* u  x: x% i$ y
  3.   /* Prevent unused argument(s) compilation warning */7 Q" @# U' u' n3 E
  4.   UNUSED(hrtc);
    ; c3 C: J! ]! E! |  O

  5. 0 S- E5 n) L& ]0 Y
  6.   /* NOTE : This function should not be modified, when the callback is needed,
    ! G4 @0 l! r/ x. o5 _; ~
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file* z% D) L' p; k& n: H, k# x
  8.    */
    ) ?. c1 e& S; ]' N" m7 S0 A

  9. & E% K7 A5 G4 b  {- S
  10.         flag =1;
    5 x) @+ B, l6 Y: U% a
  11. //        NVIC_SystemReset();3 m' n. j4 m3 D3 S3 a" R5 n
  12.         : ~; A7 o4 Y7 h4 O3 z
  13. }
复制代码

* }, r: \; w/ I7 K8 d 5.在main函数中5秒的时候进入低功耗模式
9 U) f. q, m# E0 i
  1. /* USER CODE BEGIN 2 */1 p1 R) S2 c$ w
  2.         uint8_t sec=0;8 l2 z" ?' @/ v% o
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)( }4 V0 z- e; X, R1 q, P% z
  4.   {
    3 A5 d' H, t6 E: a' a
  5.     /* Clear Standby flag */
    ; m* Q2 M1 T' H9 @! g
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);. z' I+ o% D0 L: Z
  7.                 printf("wake up from standby!");
    4 g5 ?, j1 B- |, c
  8.     /* Check and Clear the Wakeup flag */
      G+ o+ e  X* H* X3 D1 c7 A5 P
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)3 g- e2 y# p7 u$ a" c: k9 e8 s, I
  10.     {
    9 K) n1 R7 ^8 G# F- M" P0 J
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    5 J* A" v" ]% O" l2 d' f: S! F& W
  12.     }# H! U- A' R) q$ u2 D
  13.                
    , Q1 a: {; P5 x7 A) M0 {$ D
  14.     /* Wait that user release the User push-button */9 O+ s% i- \0 R
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}" K! ~. d  P2 S7 O
  16. % r( \1 w% ?2 F9 ?' @
  17.   }
    # W1 p! |" K% e  C* K4 q
  18. ; A# F! ~* _' l( }. z- `2 [' M

  19.   v* Z1 Z5 m3 v
  20.   /* USER CODE END 2 */# K/ S# s2 E$ n

  21. ) j; V, F; C5 `1 }: W) M0 ^
  22.   /* Infinite loop */  L6 j" d# p) }) D5 {9 v
  23.   /* USER CODE BEGIN WHILE */
    ) k# \1 W' P- Q) ~$ L" ]
  24.   while (1)% W: o0 H% ^1 j% s& b- H1 N, }( {
  25.   {
    % l$ ]8 R# c& g3 L8 E
  26.     /* USER CODE END WHILE */+ l9 @; Z' L3 v5 x0 z
  27. 7 s! |: n/ @7 b  U% P6 v
  28.     /* USER CODE BEGIN 3 */
    8 c. Q5 h0 G3 _; w
  29.                 RTC_TimeShow(aShowTime);
    ; d2 Y! i2 E. A
  30.                 if(sec == 0)flag=0;
    . G4 L2 _  S: d9 L/ q( f) Q8 H
  31. ! x% \$ m2 O& U5 T2 m
  32.                 if(sec == 5)Sys_Enter_Standby();% B# |( |5 n8 n
  33.                 if(sec!=stimestructureget.Seconds)
    / e0 y5 h4 P- {5 @: N9 E
  34.                 {
    8 ]4 c4 z6 T5 r, \
  35.                         sec=stimestructureget.Seconds;$ P$ H. F$ K) e9 w) w
  36.                         printf("%s",(char *)aShowTime);: u, z6 P$ G3 L( H  [
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);% U6 t0 O! M: g1 ?
  38.                 }
    / Y* a! T: J# _
  39.   }
    2 ^; a( Y: F, h1 J+ W
  40.   /* USER CODE END 3 */8 E3 J4 k1 ^$ U3 k! F. `2 L
  41. }
复制代码
5 }2 d4 H, G" q/ Z
至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。
0 T7 a, m1 g) n8 J2 A. g. s" ~% k) _
5 Q* j1 q, a# r$ i& h# D附加 避免上电自动配置RTC时钟3 F9 m/ W* c1 L& ]8 m7 E/ z% J
  1. /* USER CODE BEGIN Check_RTC_BKUP */
    7 ]* F. k5 ~6 _# ~: t1 C
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}2 d7 j3 ~. A& @% x$ A" D
  3.         else{return;}
    + P1 [0 j; M# O3 \4 W8 B# D
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码

& a: C7 z) s9 b: z8 H9 x$ n# |" t以上代码请添加于MX_RTC_Init(void)中7 q' L$ E' ]! w
9 F3 L9 H, E: r- E5 O
2019051001272486.png

3 p" k% J# C3 K/ S) L0 r
( C5 J9 Z* Y1 w# a项目文件
2 ^3 i- U& B$ [  K
& t% u& p  f* b  G
20190510013203724.png
4 D1 F: k7 d+ k5 [

, a- |' l( v- K) M# k! P% w: b/ m+ L$ T& e: c8 P; r
收藏 评论0 发布时间:2021-11-8 15:49

举报

0个回答

所属标签

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