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

【经验分享】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。
0 t& h8 j( ]' n$ C5 B2 n# X6 ~3 |5 R4 D6 I% N4 S3 E
首先配置时钟、UART、RTC和中断。7 Y; o9 v" q. M9 |  w1 l7 ^

( k7 s) B$ D8 ^0 `; N: l* v; ?
20190510004029552.png

3 Y) K5 A9 f. x# |6 e! t7 j% Q9 k, u8 x5 L3 K1 N
RCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认. u$ D( j3 j7 r0 z4 |
" q' v  x. ?' q9 r7 J: l
20190510004154456.png

% `* V' j& u) t+ T3 h
. {6 t+ q$ j$ z+ b2 n& X5 FSYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的6 B* P! A7 L: G7 W7 E& b# t
. J% p  w) M1 _" J
20190510005141588.png
7 E, \* r& E  ]; M$ p6 ^
' I( N& f. y7 h3 U
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)
% T7 X$ u+ O: f/ i% V9 M5 A% G2 {; Z2 ?
20190510005211104.png
7 c% P. I$ t% t3 R5 x7 M/ X$ u

$ N4 ~" P! v$ A& D  q  U& M7 _设置串口
& @8 x9 m# F! e3 |0 E  I6 A/ _2 F
0 S% C% ~- z! z+ n0 ?8 b; a
20190510005241164.png

) W* B- K# B2 _) g4 s2 }% B9 x
+ }9 i' |- B  I' ~打开中断入口
' @3 i) ?' _5 G1 ]$ t2 f4 t& j8 k; P- g; M0 H: m5 y
2019051000534771.png

) y5 f$ N  Q" c5 D. S) I2 i
& v/ ~+ N! x) M  v, f( `
20190510005358325.png
+ P- @* f2 ~& T4 L

# @- o0 k7 p$ r1 O) L' d完成设置后点击生成代码创建工程
4 j' T9 D' T6 m- g$ ?
% E9 I: w9 l+ H2 m- a: w1.首先喜闻乐见的printf函数% d* Y  X  M' E7 ^% b
  1. /* USER CODE BEGIN Includes */
    4 `0 t  O6 Y1 M2 T6 v
  2. #include "stdio.h"
    ( }5 B  O4 ^- X; G
  3. /* USER CODE END Includes */5 F( N! b4 j* ~. k! M& ^$ c0 M/ ~* f

  4. ; L7 z7 y+ f- Y4 X$ ]" u/ W

  5. 7 z3 E" I# {: m3 G+ U( C

  6. 6 I; d2 g: n5 `- N8 I
  7. #ifdef __GNUC__
    1 h6 s! x% s, P* ~: I
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf+ Q& F8 A/ p) P6 {/ x
  9.      set to 'Yes') calls __io_putchar() */) x2 H4 I7 K! u# N8 H: G+ \
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)4 |3 c' l5 k& b0 _. _
  11. #else) D0 L% D; I. B6 l" I1 F' b0 g
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    5 e* U8 M6 |' |# D3 i
  13. #endif /* __GNUC__ */
    2 }# ]/ I, C0 S( k4 n6 U5 m5 V
  14. PUTCHAR_PROTOTYPE
    + \  A1 h! S: ^& O# p
  15. {
    6 k/ o6 s  C- F+ C+ t
  16.   /* Place your implementation of fputc here */- z% D! N  T; a4 Z, {! e+ B
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    8 d5 h* U5 l1 F0 f3 J& k, Z
  18. ( |: ~4 X$ R& H( S
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
    ' I  l, Z: h# [$ z" ~6 m/ v
  20.         / x3 @, ~6 d6 X9 U% u1 @
  21.   return ch;; t8 g/ F& {* ]' i9 b) e" `
  22. }
复制代码

# r. s( G& D: w6 Z' n( H1 }2.RTC时间获取函数7 o, G' X& m. Y5 {# Q! {

+ `5 d  N' A, J- S! v" {
  1. /* USER CODE BEGIN PTD */* g7 a9 W0 C4 f* G& v. g
  2. RTC_DateTypeDef sdatestructureget;2 W3 {# d) c6 |/ }4 ^4 k% T" a8 A
  3. RTC_TimeTypeDef stimestructureget;$ f; ]+ ^( r3 [; S1 p+ f
  4. uint8_t aShowTime[16] = "hh:ms:ss";
    + r* Q: S3 t& \2 l
  5. /* USER CODE END PTD */- h& d) G7 b& g3 b3 A! \* S3 M
  6. , e. a; e0 G$ r- I4 k6 T
  7. /* USER CODE BEGIN PD */% q/ Q+ B& M' ]. M: h8 W) g
  8. static void RTC_TimeShow(uint8_t *showtime);- [9 S  }% j) q& G" n, }* e" H6 l
  9. /* USER CODE END PD */
    & p* J+ L# ^% o9 g9 x  ]2 C

  10. ; C6 W8 T% I/ @3 D6 D3 y9 j

  11. ! ?. X" z; N" l6 v+ x1 f
  12. static void RTC_TimeShow(uint8_t *showtime)
    5 k! F0 H% v1 T/ I' l
  13. {# s, f; r2 t( Y( Q5 n% u
  14. ; X8 p( m/ O, T/ y4 {
  15. + p4 n, l0 n/ g3 ^5 N) ?
  16.   /* Get the RTC current Time */% ]) G: g. ~9 v! q4 k' [8 n- p3 h- {
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
      x( H/ K6 G! i5 ]6 T1 ^
  18.   /* Get the RTC current Date */# U% C) E3 ^0 Y& b+ M9 M
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
    ; q8 Z/ q, g* s! y+ I/ r- R
  20.   /* Display time Format : hh:mm:ss */+ a& t2 S4 x0 @, L5 j
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
    # W5 T2 W" T' r
  22. }
复制代码

- L3 l; n) v- s3.standby进入函数
1 q' G* e! k2 F* W
  1. /* USER CODE BEGIN PD */
    & e1 `8 H# ]3 Z: o
  2. void Sys_Enter_Standby(void);: X. y0 k: I( O7 a. [7 a. P
  3. /* USER CODE END PD */
    - \0 U. m: `5 t' D/ F

  4. 1 b" e  L+ }, c& W
  5. void Sys_Enter_Standby(void)
    : Y, q' h7 d& Z6 Q& R. u) }
  6. {
    / ]2 A9 ^" `! L0 d/ A" {8 k8 Z- n6 J
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry
    & k6 f: T3 x: l9 _: s2 z" A+ u
  8.   - Enable wakeup3 F5 k4 I0 ]" f
  9.   - Clear wake up pin flag depending in edge detection & pin level.
    9 y& Y  J1 Q: J: F: R) p* [5 r7 P
  10.   - Enter the Standby mode.3 A( [  l0 h6 A! F1 \( g7 C( s5 u# g
  11.   */
    4 h7 ^( H1 O0 d* ?) k  J

  12. ; s  _' q! O9 t1 I$ s+ k  X( \
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */& K9 E$ p) O# F& y2 Z
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发
    3 s+ r# S& a1 P
  15.   HAL_PWREx_EnableInternalWakeUpLine();
    9 Y- \. J& `' q/ Y! `
  16.   /* Clear all related wakeup flags*/
    ; _$ U+ G* d5 x3 y  g
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    ( R7 H" u9 k* O6 a+ G8 y
  18. " R- m  `* K7 {4 C
  19.   /* Enter the Standby mode */# k, @% ?, i8 P$ c% f% P+ R: g
  20.   //HAL_PWR_EnterSTANDBYMode();
    * u9 p& L+ E4 }
  21.         printf("enter Shutdown Mode!");4 {, K2 q( E! r
  22.         HAL_PWREx_EnterSHUTDOWNMode();( ^1 {: O9 K. ?7 D) V1 {
  23. 9 o+ ^3 w) X( b+ W
  24.   /* This code will never be reached! */
    3 K9 _( K0 r$ e4 c2 {, e
  25. }
复制代码

2 C; b9 T# {" p# C; L+ j4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)3 d2 ]0 a3 q. y! g0 _# K. v6 J6 F
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)5 M) y0 n- q7 E" m
  2. {
      A3 p+ j0 Z, Q
  3.   /* Prevent unused argument(s) compilation warning */
      C* l8 [/ a. q6 z' S$ {5 p- J
  4.   UNUSED(hrtc);
    7 ]2 p, j) ^6 R8 A

  5. 2 C& N8 U$ [4 a# y6 c" R
  6.   /* NOTE : This function should not be modified, when the callback is needed," A% z9 N2 t8 e7 v9 E9 {4 D' z& q4 y
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file8 A1 K: i+ M9 {  I) v
  8.    */
    & U, @* G' M4 y/ k  h
  9. + Z8 X! X7 e8 p/ k1 b& Y% S5 g5 [
  10.         flag =1;! ]- k% w7 g$ U0 h! J7 `( z2 u
  11. //        NVIC_SystemReset();
    7 _: }, F6 y  N6 J3 O5 w
  12.           C4 ~# m) h6 r2 g/ K9 M0 _
  13. }
复制代码
! k& E( D* ?8 e3 i: V. M9 F
5.在main函数中5秒的时候进入低功耗模式
# ?# c2 i0 c7 w( g
  1. /* USER CODE BEGIN 2 */+ ]( M5 ]( |' ^3 K# L  B
  2.         uint8_t sec=0;
    0 a- @0 ^* O4 G6 C; h: k- b
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
    - n$ D, C5 E) h% K4 g! o) h
  4.   {: R1 d; i, D0 m$ F2 i# `6 d
  5.     /* Clear Standby flag */1 h0 r3 ?$ C3 F6 F+ p0 G: u
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    + {0 m9 b+ K/ \7 y. {
  7.                 printf("wake up from standby!");
      j" A0 d, M3 e! a8 J
  8.     /* Check and Clear the Wakeup flag */& v" n$ g2 t8 G" h' F
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
      t8 A8 a7 o8 R, }
  10.     {6 C2 F0 F# @9 P- ^* K- s3 h) u
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);9 X; K! \: L7 T5 S! }3 B
  12.     }
    ' a8 C- s: X" Z* o
  13.                 " f: m$ `: R' X8 v
  14.     /* Wait that user release the User push-button */" [. L6 D* e1 A. ^! d7 h/ b5 n7 K
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}* l3 [- |) u6 {5 G* E

  16. ! {6 U* y9 c& A  m
  17.   }# R7 [* [/ _/ o/ `1 ^3 c+ R2 Z- c
  18. 3 M( `3 ?* }& |# q' k

  19. 5 T9 r& D4 g& _3 y3 N+ H
  20.   /* USER CODE END 2 */6 g" `/ ?1 v9 e8 h
  21. " ?' W, r; ?; U7 l, \) \. e6 K
  22.   /* Infinite loop */4 R  p  [1 M1 B! M$ o
  23.   /* USER CODE BEGIN WHILE */
    , }  y- K$ L6 s$ P" _1 g" _# v! f
  24.   while (1)0 b) L5 [6 X6 L# q/ u0 L
  25.   {
    , i" V7 {* h  S5 y1 z+ A
  26.     /* USER CODE END WHILE */
    ) k3 [: b5 J* m8 R+ z5 N% X$ k+ G! i
  27. ! t" m  A( Y0 C
  28.     /* USER CODE BEGIN 3 */
    ' Q; O* {6 x9 B( g
  29.                 RTC_TimeShow(aShowTime);
    + \5 S: J. w" v7 p$ Q
  30.                 if(sec == 0)flag=0;
    5 `8 j" l  |) m* }# X
  31. 1 A: G# C) h' Z0 F
  32.                 if(sec == 5)Sys_Enter_Standby();
    5 Q) g' f( M9 G' q& s9 b
  33.                 if(sec!=stimestructureget.Seconds)) U& I- S  Z' i! p; _# g
  34.                 {) T. h+ e& I" A
  35.                         sec=stimestructureget.Seconds;" U3 B& i2 q3 ?( S1 _# x
  36.                         printf("%s",(char *)aShowTime);
    ) s) l# y& Q/ {7 x
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);9 ]& V3 o. D. i- V( S0 Q
  38.                 }
    7 P3 H. o3 E* C/ ]  P
  39.   }% F- ^3 ~. R" s* q
  40.   /* USER CODE END 3 */! `1 e2 \1 O' r. c- D9 p9 h
  41. }
复制代码

* P: n9 j# E. |2 @! ?至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。: q2 c( Z2 X! [# b
# C+ w5 q; d# I/ \8 Y  ^
附加 避免上电自动配置RTC时钟3 \2 R5 m1 \0 C' ~) l: z
  1. /* USER CODE BEGIN Check_RTC_BKUP */
    . {# @; M7 n- [# H5 t# H0 s
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}( b, I5 u6 j( V3 X
  3.         else{return;}& G+ z1 O+ z8 G5 t6 `% V: }6 y
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码

( P! F1 F$ ~: {* x- k以上代码请添加于MX_RTC_Init(void)中, d# Z, i( ]4 k# h0 C

4 P  u" `. d. u! |& t
2019051001272486.png
' o# I/ _" d* f
8 }1 e" X0 N3 M8 s
项目文件
! b) j6 T6 M! R3 [
7 v0 A. R+ x; F: C# S, c. h7 x
20190510013203724.png

" t& p( a$ s( W- n$ y) s. o6 T  l8 z2 o: U3 J
8 u3 e6 c" X! r
收藏 评论0 发布时间:2021-11-8 15:49

举报

0个回答

所属标签

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