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

【经验分享】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。$ y: U5 |4 W$ j. V: K: `- D* y+ F0 G

0 G& a. I- z7 @; P' V  l首先配置时钟、UART、RTC和中断。
" T! p, ]( k5 r  o. S; C
7 P: k# `" T, b7 u, W: J( U
20190510004029552.png
% I* l, t6 ~3 g; ]8 z% m) }( F

6 Y. H& L# `5 C) p" ERCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认
# L( ]8 a2 ?& v- E- s5 s2 c3 H! x! a
20190510004154456.png
3 J% r' P% O+ M1 p7 s* b' ?' ?
( Y6 w% n, r# c+ o* I! M
SYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的: n' s. t7 W5 V/ U" j' n$ ]% |/ N
# T+ v' p' _1 e
20190510005141588.png
* [2 H, ~6 \/ i6 H. s- Z! I
  J; x3 ^% O1 l% P
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)
! l8 y1 ?' @$ `7 ?8 P" e# j3 _# M& ]0 P5 T/ N+ d7 q( s0 T
20190510005211104.png

0 A1 n: v& [' W7 X3 F  a& v% J+ R% T. X7 ^. J
设置串口/ X& @3 ~- R4 L( f/ I
1 K/ {, t5 C; P" g  s1 ]
20190510005241164.png

4 A' h2 I5 T$ e. ]
7 x, Y" w& N, x6 W. R打开中断入口+ L; A8 r1 b+ o2 F; u  n- c1 v  q

, D$ |+ P# D( P& y6 ^
2019051000534771.png
4 l3 [: {& p6 M5 y2 q0 u5 B
% ]8 g6 j, o" k- K, \
20190510005358325.png
+ e3 G2 k4 z% V5 Q2 o4 M- _
* E1 `7 G0 w  U
完成设置后点击生成代码创建工程0 Q$ \: d) h' E4 t; Z# q

4 a6 k* V% u! b8 g. T" i1.首先喜闻乐见的printf函数
1 w8 @6 [* z: ~
  1. /* USER CODE BEGIN Includes */
    : P  V. w! O7 V9 B. K0 j7 s
  2. #include "stdio.h". G0 V. Q( r. Y+ G8 m; _
  3. /* USER CODE END Includes */: l* }$ n# c- @+ U; I$ d

  4. ) ~  [4 a  Z3 z
  5. 3 G6 M  r9 L- O8 O8 I0 Q% J$ b
  6. 1 [8 B6 v( ?1 H& ]+ g' b7 E& C. |8 l7 T
  7. #ifdef __GNUC__/ f0 x# O+ M, k- l  K
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    ; J% i' B5 |# J* P5 t
  9.      set to 'Yes') calls __io_putchar() */' {* v+ U0 l& |
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)" Z( o) o7 X6 w. |& q/ ~7 V3 d
  11. #else
    / ^$ g9 I9 G; n" f& |  v! K1 j
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f). L, i6 S) r  o
  13. #endif /* __GNUC__ */, u- M# [4 E$ ~8 _* Q5 o; Z
  14. PUTCHAR_PROTOTYPE% q3 {  r, I  o" E" ?/ G6 _+ d
  15. {9 N9 V, ?+ g. m
  16.   /* Place your implementation of fputc here */
    0 Z2 z' ?4 F% g4 J1 I6 x4 C6 ~
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    2 y! u/ o, }% u& d9 }
  18. $ u4 k  S0 F9 `1 k% Y' i  f
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
    " D2 C; Z9 O: r1 j1 N5 ^" G/ z$ y% [% p; D
  20.         . u* r' z* a. O# Z6 }
  21.   return ch;
    8 }" _( r# X  d5 `
  22. }
复制代码
$ W9 W( W8 l: ]. \4 q6 K4 S# H
2.RTC时间获取函数! p' l# Q; l" ~& ]0 L
. Y& P# N5 w5 n, g& U  t& X: t
  1. /* USER CODE BEGIN PTD */
    6 O1 D8 S7 i6 y# H3 @* P: U
  2. RTC_DateTypeDef sdatestructureget;7 m' q" r1 g# H
  3. RTC_TimeTypeDef stimestructureget;
    0 l4 o# q/ b( E7 A6 {$ W
  4. uint8_t aShowTime[16] = "hh:ms:ss";
    ( ]% `* d( k( o  j2 Y, x
  5. /* USER CODE END PTD */; ^/ [4 C" g' N

  6. , n5 Z* v) V1 [6 }8 O! G: y9 ]
  7. /* USER CODE BEGIN PD */0 _2 C- A2 K5 |% J' f# q# V
  8. static void RTC_TimeShow(uint8_t *showtime);% f3 }1 I% `3 B* N
  9. /* USER CODE END PD */
      H& r! ?  Y( D5 M
  10. + Q/ R. W6 [; i+ J5 c
  11. % Z# }6 E& [/ b% y$ r  `3 v) f  i4 `
  12. static void RTC_TimeShow(uint8_t *showtime): f( T* P) ?  Z5 e2 G5 A
  13. {
    : |' r9 K3 w% y$ \

  14. ; X3 \+ Y8 ^2 j! O# Q& U- R

  15. 1 r& ^0 K7 J+ ?# k! ~2 b
  16.   /* Get the RTC current Time */9 K3 F% ^! X( ]7 s# ?2 o  X) q7 ?9 b
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
    4 `: ]1 _- H; K& u1 r  D- h
  18.   /* Get the RTC current Date */
    6 ]- C/ |4 J5 j4 d! w" |
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);8 v% ~" o3 C) I1 D
  20.   /* Display time Format : hh:mm:ss */
    - g: j0 X( I. E- z0 \, o0 F
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);" F2 F5 @$ q" v6 ]1 d
  22. }
复制代码
' ~) q# M! e9 X- u6 U
3.standby进入函数
% V2 R5 E4 I. S
  1. /* USER CODE BEGIN PD */& A/ k) p! k+ B' s
  2. void Sys_Enter_Standby(void);
    & F7 Y  i* s4 j1 e
  3. /* USER CODE END PD */
    4 d2 v; @  [6 o; }( M$ D. M

  4. % P2 ?% A6 z( e/ O
  5. void Sys_Enter_Standby(void)% R; Q  o* L6 |. W% r
  6. {
    $ T* g+ R6 g" ?' a
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry
    9 W" M9 p6 A& H( D6 t, D
  8.   - Enable wakeup9 d9 M1 B9 a: E7 A0 }
  9.   - Clear wake up pin flag depending in edge detection & pin level.  t$ O9 Z* Q1 ?
  10.   - Enter the Standby mode.1 u4 x5 s2 [: w! h; G: h
  11.   */5 h7 n% y) M$ K5 ~
  12. ( x" h$ n9 w5 X8 l+ z3 ^1 i
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */
      x/ ]8 Q7 d  J/ E
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发# @6 G. k; `! F) e
  15.   HAL_PWREx_EnableInternalWakeUpLine();3 z9 R" t( D8 c2 \
  16.   /* Clear all related wakeup flags*/
    $ j9 R, t9 _- p; k! b1 `
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);. b$ U! P# u( H
  18. ( g" u; l4 ~; C
  19.   /* Enter the Standby mode */# _: q8 i% M7 N! k1 Z, b/ ~
  20.   //HAL_PWR_EnterSTANDBYMode();) z, n4 a! z+ ]+ }# {! n
  21.         printf("enter Shutdown Mode!");% a1 J* t  j# X  t/ W2 M  _1 n
  22.         HAL_PWREx_EnterSHUTDOWNMode();! ~! O% e; O* z1 `

  23. 1 K" |& D# S* w+ ?: j/ g, W
  24.   /* This code will never be reached! */
    7 ?% L- d) O. D3 Q
  25. }
复制代码
; f% b# o7 P# ^& J( ]* `9 E. o
4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)6 u" F( E4 ^9 t4 D$ F! G
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
    ( T4 [- j! E- u: K  e# ^9 ]( G
  2. {9 M; P2 i- }; l8 ^
  3.   /* Prevent unused argument(s) compilation warning */* b/ Q/ H% p, L7 N  L
  4.   UNUSED(hrtc);/ T- A- O' q" f6 w. h# T4 \

  5.   e. ^: o4 X* I  @
  6.   /* NOTE : This function should not be modified, when the callback is needed,) K9 R# j0 e0 `: Y
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file1 z4 J/ d) |. w! m5 J/ m9 ?! R
  8.    */+ d6 @7 _  p" j7 _6 }! p

  9. / H6 E$ T! {/ v- V% m
  10.         flag =1;5 w8 s% a5 `, Z7 s6 N( l$ a: Z: t
  11. //        NVIC_SystemReset();
    ! ^7 x* W% B. U3 p5 r9 v
  12.         6 E& A' G# m$ H/ \! p8 {
  13. }
复制代码

1 B" L$ }: E+ R2 a& e9 R 5.在main函数中5秒的时候进入低功耗模式1 Q# m8 M1 w. u: z) O+ x
  1. /* USER CODE BEGIN 2 */( s' m7 x( F8 L1 e+ {+ @/ Z
  2.         uint8_t sec=0;  N( [9 a* |: j3 y4 g4 Q% S2 b
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)% w- G; {5 ^+ |# Y3 ?" a) F
  4.   {
    # Q3 p) N6 H  Z, _1 T
  5.     /* Clear Standby flag */; K7 B- R/ n+ F! w: ~
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    ( R# K# L2 j. L' `. J# I, ~
  7.                 printf("wake up from standby!");
    2 j- b8 ]/ b" L
  8.     /* Check and Clear the Wakeup flag */3 V- u' k( d2 i4 O/ M
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)1 P8 x  Q- `* G; G  Q8 g
  10.     {# z- N2 E% G# r. l- J$ f; l
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);, @. W) E+ I, v* [& Z6 b& L
  12.     }
    ! U' \" Q: _% h5 ~! x  N" M9 n
  13.                 + D: u" ^( L7 a1 }6 [1 G7 y( W
  14.     /* Wait that user release the User push-button */7 b1 ^. t  ?: l2 X
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}
    : O# N* l) s! t( V3 x
  16. 2 z  N0 _; q$ H7 R" _
  17.   }
    $ I& ]" ]7 }4 {  A/ }5 }

  18. : l- g4 K8 u9 ^" F" q' c( U* N1 E

  19. $ w$ B2 {: P) A$ k+ o
  20.   /* USER CODE END 2 */7 k7 g: l6 s3 t0 G  q. K
  21. * Z& x( Y! ]1 n
  22.   /* Infinite loop */
    % ^0 |# S7 N. l
  23.   /* USER CODE BEGIN WHILE */
    7 R) ?- v  w: Q0 Q' i# f" [
  24.   while (1)! `5 Y( B& k* v6 D: |
  25.   {; B& x' M1 d* D1 T. t7 l
  26.     /* USER CODE END WHILE */
    7 e0 F" F5 |$ k) M. Y5 H

  27. 6 i: v# p# F  X3 |& ^, w
  28.     /* USER CODE BEGIN 3 */
    . X/ ?" C' ~3 i$ z9 j$ y/ T
  29.                 RTC_TimeShow(aShowTime);& R0 y. N  a  H+ J
  30.                 if(sec == 0)flag=0;
    7 t) p. {' T5 g) L2 v$ T
  31. ; i4 h6 B, M( f' c! w
  32.                 if(sec == 5)Sys_Enter_Standby();+ O* r6 s- p4 `# E- P' F# O
  33.                 if(sec!=stimestructureget.Seconds)1 f9 h. R' w5 h! h0 h8 q
  34.                 {5 j6 F3 F+ Y4 W* V7 c
  35.                         sec=stimestructureget.Seconds;: ^+ W1 x. Y. z+ n
  36.                         printf("%s",(char *)aShowTime);
    8 ?0 ?5 r- X$ P9 ]
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);4 B( Y" L9 F4 E* i3 u7 U2 u: w
  38.                 }$ N0 f; k6 G2 S% d, Y( O" r
  39.   }
    5 W0 Z. l" h# ~( @
  40.   /* USER CODE END 3 */
    4 K" F4 M$ L: v% b
  41. }
复制代码
3 e# t4 G1 q/ g3 L: K0 p5 K
至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。
! A2 I: ~! l0 w% G4 d7 [
7 Z$ q- K! W) ]7 x6 v附加 避免上电自动配置RTC时钟
& M. D2 B% X- Q% T+ H; R" p2 m
  1. /* USER CODE BEGIN Check_RTC_BKUP */* X, y7 [" i4 l2 K2 Q) c
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}
    + A9 J- G7 J( Q, T! o+ E( b6 }
  3.         else{return;}
    $ j! |0 z* B  p% i  ?+ o
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码

$ q$ t# g; \, u4 B9 f4 E( b以上代码请添加于MX_RTC_Init(void)中, p& w4 F* X( {: q  \9 d

+ i0 e# V( l- ?- Z
2019051001272486.png

1 o5 S7 i/ V% }/ k3 |6 {+ \6 a, {
% b& e# I% F' l: z4 L/ H项目文件
% h* w. s7 `- P' ]7 V
* b* |* H& ]# p- r/ ^% W
20190510013203724.png

: M7 k+ s* e  e: O( E: _
. U% c7 {* l+ z
4 U  }: {. A, g8 D$ c& T6 W
收藏 评论0 发布时间:2021-11-8 15:49

举报

0个回答

所属标签

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