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

【经验分享】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。
, D' L0 s" X9 V5 L( K& ]
  L0 ?+ z5 Y3 v2 h) X# [* h首先配置时钟、UART、RTC和中断。
; v% o; z! m: a- O/ }  H* j# i% s+ W# R2 Z9 l, Z" D
20190510004029552.png

- v. y; `  h: \/ u
5 F- |6 h% y: [" PRCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认
( m9 U+ B5 A  a. V3 T6 N1 @
2 l7 f; b! g6 V
20190510004154456.png

% B6 J! E; @& R! |
+ G# m' N1 R- c; b( m, i+ TSYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的
1 Z  G0 p, ?: V9 u! B* r( W
" ~5 ]' H. q) ^5 k/ I$ N3 m4 a7 S: v
20190510005141588.png
8 T$ h; h3 g5 L7 L/ M6 x7 R0 f
$ k, |( P, X! t1 E' I' G
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)
$ i7 E' \: ^) {0 ~3 B) r- Q% L
* O: N* m& v2 p) D; R0 P7 O
20190510005211104.png

; K8 @( L6 {5 i3 m- s" H! [
+ m+ O& i0 R/ k- l2 S4 U设置串口
. W6 i0 F$ P! y' _; {; @& \& ]" ?/ \2 l' F8 J
20190510005241164.png

' Z" H) B4 |5 ]2 I. j7 t, j1 M$ ^3 X( k: z+ y! Y+ d7 ~- S4 `7 M5 d
打开中断入口
% ?7 R# S/ B- ]0 m( n2 [, ?; _8 A1 N- Q6 Y6 I
2019051000534771.png

9 W/ E& `* A( M5 u/ f0 ^: d# M
# _7 M& i( p3 `1 I  H
20190510005358325.png
0 C. b) h2 z8 d3 Z

; }+ c/ P; c5 S' X. _2 u完成设置后点击生成代码创建工程  ]* |0 ]* k! Q) s- o: D
: t! |# d3 F8 E2 {, @* F7 u4 w
1.首先喜闻乐见的printf函数
0 e# q$ _; B* j. U" F
  1. /* USER CODE BEGIN Includes */: s5 w5 z( `+ T6 H/ R3 ^
  2. #include "stdio.h"
    2 ]& \7 _8 M) s0 b' n
  3. /* USER CODE END Includes */
    8 m0 s( Q* g" x: _+ g

  4. 7 L$ u: m2 C& N5 [( e# Z+ Y, I  U& x

  5. 9 M/ N3 J0 r# q( Z1 v1 \! d

  6.   U' ]* H* A( W7 h7 m  F$ A
  7. #ifdef __GNUC__
      f; t7 Z; E. Q
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    0 ?4 R" r5 Q) j, H' \
  9.      set to 'Yes') calls __io_putchar() */* B8 a- @2 z' b) F
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    $ \; g3 G1 x; ~/ X& a) c
  11. #else) ^+ ^+ H" P7 u$ {# D8 B8 @- K
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)( R' C4 Q$ f: \: b
  13. #endif /* __GNUC__ */
    ! t: W4 ~" P% `) _
  14. PUTCHAR_PROTOTYPE
    * _. e7 X7 t# }( J
  15. {- `! f& y" O) s3 S
  16.   /* Place your implementation of fputc here */! O, c- ^- I( w0 X
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */5 D- n  v, i7 r& |

  18. 7 j' m% P" `3 ]4 |
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);& L! R( j/ N5 B8 {, d1 D1 a
  20.           Y/ W+ y5 c! z$ R6 }9 ?. e
  21.   return ch;
    1 ]5 f# B% E! {- J' S" f! _5 ?
  22. }
复制代码
% F2 `8 H; @7 B+ P& [& V
2.RTC时间获取函数
5 A7 ~2 |5 C6 d9 O
# T+ g' A9 q6 Z  {2 y& {/ D
  1. /* USER CODE BEGIN PTD */( ]  d0 d9 T$ K/ K1 x4 w
  2. RTC_DateTypeDef sdatestructureget;/ R5 T( |6 ~7 [& D: C3 P4 s3 ^+ y9 j
  3. RTC_TimeTypeDef stimestructureget;' U9 `' I% \) X5 \+ D9 B
  4. uint8_t aShowTime[16] = "hh:ms:ss";  q" w6 v6 ?' m0 G% r
  5. /* USER CODE END PTD */
    . v3 W  j& _8 a, H. S: o
  6. & h  M% V2 @$ B* z1 a
  7. /* USER CODE BEGIN PD */; R, d" U* j( d' j+ b% M$ y2 t
  8. static void RTC_TimeShow(uint8_t *showtime);! l3 A6 R( H1 k
  9. /* USER CODE END PD */: M5 }0 h! K' X' M

  10. 3 \& O' Z7 i1 L: t' E8 a. M
  11. ! R( ~* w7 g6 M' A
  12. static void RTC_TimeShow(uint8_t *showtime)+ C& g! p) W$ |/ f& N: Z: `
  13. {
    8 h8 o: W! S0 L0 U

  14. 7 {# V9 w9 r, ~& A9 v0 C$ Y

  15. . k# Y& G4 W1 ]& @$ q
  16.   /* Get the RTC current Time */
    0 ^" J- n/ O8 l; i! i* Y* M* g3 f
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
    3 }6 I7 q7 O' I- V: M7 P
  18.   /* Get the RTC current Date */
    4 g5 L/ |/ Q2 c$ R- {+ E
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);. `5 F4 }* k3 D
  20.   /* Display time Format : hh:mm:ss */! p; G' j0 T8 `
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);, B# J' Z2 F! B  M% s, b
  22. }
复制代码

, ]- {! l2 A# t5 ^' L) B3.standby进入函数6 _( ~6 S. O5 Z9 p6 R
  1. /* USER CODE BEGIN PD */7 ~* c& f. @- D
  2. void Sys_Enter_Standby(void);% F$ K5 D4 [- \0 b
  3. /* USER CODE END PD */6 C$ n! d6 P) P; a

  4. * A  B0 I  Y9 v9 q
  5. void Sys_Enter_Standby(void), j- J5 J* Z7 E+ y  t
  6. {' I3 q% \0 f* V! a
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry& y. M& t- t! S& q
  8.   - Enable wakeup% H( _$ ?2 K3 P: x9 }8 N5 A
  9.   - Clear wake up pin flag depending in edge detection & pin level.
    + e+ j5 \9 Y0 l. @5 q8 c6 ^0 l
  10.   - Enter the Standby mode.. t) l4 a* J. H& v: N7 Z
  11.   */
    4 X/ h( J6 G4 s9 @) U# M6 c

  12. # R5 F% [! L+ ]- i
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */. d/ U# l4 l  R
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发( U& A  v" k  l; B# z! _# b) S  _) S
  15.   HAL_PWREx_EnableInternalWakeUpLine();
    * g5 }  z& L0 _
  16.   /* Clear all related wakeup flags*/
      {% m- H& n8 h2 d
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    " t+ F7 i( D% O  o/ N. h# s
  18. # {0 p, e+ t5 K8 I1 V% s
  19.   /* Enter the Standby mode */
    , |. l# W$ y: t2 Y
  20.   //HAL_PWR_EnterSTANDBYMode();
    , C( y8 _2 ~+ B; h) ^7 v: o
  21.         printf("enter Shutdown Mode!");
    - U- p- n& x1 l* N$ ?4 v2 q( ]  F
  22.         HAL_PWREx_EnterSHUTDOWNMode();$ f8 I+ w4 q: t) r( J& ?

  23. 7 X8 j: h! q0 D0 B
  24.   /* This code will never be reached! */
    ( j$ ?. y# B1 \  A; A
  25. }
复制代码

( m/ m5 H: p' h, f" l4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)- N4 Z; D% u. x1 h% t: w
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
    4 Z* l& b$ B. ~) U$ A& J4 G6 B
  2. {; ^6 v6 ]) i6 N; A( n/ l* o
  3.   /* Prevent unused argument(s) compilation warning */) v6 I% f- M0 H
  4.   UNUSED(hrtc);
    " P  m* F( Y& z6 j( ]$ d
  5. + Y; d9 r. z% E
  6.   /* NOTE : This function should not be modified, when the callback is needed,& f' \! ?% b7 E& }( _0 T
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file; f  O* w& `4 N
  8.    */* b! W' t9 \! u8 R/ W6 Y& _

  9. ) J/ F7 G( Q' e% Q3 |0 j
  10.         flag =1;
    9 Y: N& w9 y7 A
  11. //        NVIC_SystemReset();
    7 y' [2 v8 ?2 t  N
  12.         / n) I  [; Y* W' P
  13. }
复制代码
, f# m9 L) R1 D$ f
5.在main函数中5秒的时候进入低功耗模式
, H5 b; n" ~5 n: P
  1. /* USER CODE BEGIN 2 */
    4 k+ v: V% g" \" P3 G
  2.         uint8_t sec=0;0 A1 n  p) Z* ?6 O- @) h5 `) J
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)% J4 R# b: P  b1 A* f; [
  4.   {2 J, R% F( y# w5 P5 o" T7 X; @! t
  5.     /* Clear Standby flag */
    4 y2 L: p0 o+ D  G9 j2 r
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);3 \( ^" |" ?* u9 k$ i
  7.                 printf("wake up from standby!");
    2 }' I, m3 T6 k% ?& {4 E! B6 }
  8.     /* Check and Clear the Wakeup flag */* c6 N) p3 W3 ^! X
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
    7 `7 ?4 t% i! w2 c$ P
  10.     {
    4 ]0 y- S, D; ]# ~$ ~; T
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    * ^9 C" ]! h5 Y5 B* S% R
  12.     }
    / ^4 I4 F9 h5 v0 C# L  I7 q
  13.                 5 x0 y' n  j. @, S2 X3 U
  14.     /* Wait that user release the User push-button */1 P9 _( V/ E, V
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}
    * h( z' V; b9 E+ ]! ?/ l

  16. . c9 d$ m/ H: F$ N: [  d  s
  17.   }
    8 L) o1 s6 U: s1 w% ?7 ?9 d! e2 ~6 J
  18. ' t- G; Z' M) B- s
  19. ) b: t" `; H8 w% `. K) g
  20.   /* USER CODE END 2 */
    : P( Y2 a$ i9 L. A5 w1 d: H/ y6 I! p
  21. ; x, H) ]* o: n
  22.   /* Infinite loop */
    " P8 x! ~8 m5 I7 _6 _- u# x% ~
  23.   /* USER CODE BEGIN WHILE */. v+ `1 x0 Q( I( Z
  24.   while (1)% l+ j* I- O" P7 p$ b
  25.   {
    / M$ D" L3 F( l9 k! M- e; ?$ r
  26.     /* USER CODE END WHILE */
    2 ?4 l$ g5 H2 f6 W0 r2 I' I4 y
  27. 6 O  i  j" v1 G! J
  28.     /* USER CODE BEGIN 3 */
    ' |/ A/ u; N! s4 ]
  29.                 RTC_TimeShow(aShowTime);7 G2 K- g: p/ ]. I! b3 s: L
  30.                 if(sec == 0)flag=0;/ O! X! |! ?+ h/ W# T
  31. , X; Y: Z0 K6 `
  32.                 if(sec == 5)Sys_Enter_Standby();
    + N8 z* [9 F* Z2 q' b8 v/ G
  33.                 if(sec!=stimestructureget.Seconds)! E/ E* s# U+ c- P5 Y
  34.                 {
    ; `' K& l# [3 {0 j/ L' e
  35.                         sec=stimestructureget.Seconds;
    - l) n: R+ y% m: _1 [
  36.                         printf("%s",(char *)aShowTime);
    % G' F# k$ P' k+ C1 e
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);, i+ f8 M# L7 _  m4 O1 C& y
  38.                 }# y% `2 ]/ \2 ]0 m- R2 E! S
  39.   }6 P0 l) Y7 J5 J6 C  Q% L6 C
  40.   /* USER CODE END 3 */
    7 l9 X; u6 ~/ y) J+ ~8 l! ~
  41. }
复制代码
% T8 P1 y5 R, E" H% Y; p8 O
至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。
; c% ~0 k  L8 t7 f% h
- s# x# o# e& p1 I; w附加 避免上电自动配置RTC时钟
3 r. C# j! M3 C1 v1 m' m: J
  1. /* USER CODE BEGIN Check_RTC_BKUP */
    7 L# f0 x4 E6 D& P) F
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}
    3 i( N, N- s# T7 f
  3.         else{return;}
    5 ~8 D2 ~6 [9 I8 Q
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码
9 N5 \4 N# s& e- ?
以上代码请添加于MX_RTC_Init(void)中
' o6 ~) F3 f* d: Z( i$ l4 G3 i6 U$ l9 b! b' m9 K) |8 R% H
2019051001272486.png

* U( a) A% a# Q" ~: i% `! }0 J
: A  V/ @' c( T# `项目文件
' S$ y4 X$ G+ Z" K2 [6 N* Q! \, }) N$ f
20190510013203724.png

8 F5 O4 a8 v, V  p1 u" V! [$ v& P% D7 x5 I3 M! F) P
3 l' ^% r, U. |$ }, F# j
收藏 评论0 发布时间:2021-11-8 15:49

举报

0个回答

所属标签

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