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

【经验分享】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。1 M1 j; n8 c  U
7 h* k% A& n8 W" S
首先配置时钟、UART、RTC和中断。4 j: I  v# v8 y5 g1 K

; \6 o& s  \0 U' r6 d" s
20190510004029552.png
2 G8 `3 }# k" g% i6 i" ~8 q- A! N
7 t- ^  o& G8 Z" J, c
RCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认
1 P0 k0 Z+ S. @( i
! e- f6 o6 L1 C# X3 U9 _2 q
20190510004154456.png
2 i5 H9 L" _  R; b6 [- N
0 |) _; i* `5 Q. Y* {& K. W5 Z
SYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的, z/ S& f) X. \. c* @  k: v

* p8 v5 ~" y3 J5 z& I
20190510005141588.png

( D( x8 Q. a: a. C; J, t4 z9 @$ d; m4 f, C7 ]' X
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)) `  b' M5 ]/ e, \3 V. c# A

& S/ Y2 A7 |, }% y  [
20190510005211104.png

  j: c1 E9 X+ Z8 a) a% o* a  O9 I9 X; k* X
设置串口( A% S0 y4 t3 [. r" u; v
4 D" K  a  s1 s. z% }+ a, ~
20190510005241164.png
6 J: o8 C' M/ O3 ~* R* X

4 T9 B5 e  e5 H) h0 C打开中断入口$ N) X+ `7 `" R) z
9 ]" T" ]) K& m
2019051000534771.png

  T; n% I. z! B8 e* T4 f3 I5 {1 u; e% \% I2 G0 I
20190510005358325.png

9 d0 N! e8 b& z; n9 F, W" P
! \5 B7 A" e- t! _9 B完成设置后点击生成代码创建工程
- @' ]1 |2 i  Y  l% w8 \( x
# j/ d3 O, g1 I* X1.首先喜闻乐见的printf函数; n3 m) W5 ]7 ]4 f# J
  1. /* USER CODE BEGIN Includes */5 n4 N; n: |4 O& P% N
  2. #include "stdio.h"9 g% V0 J" }2 G  U1 i
  3. /* USER CODE END Includes */
    : b0 J1 v# V& Y  @+ R1 }

  4. / ?: f' K" ^! Z; R! `* ]: b
  5. : ?3 L; p. d; l* X& k! d
  6. 6 S5 [6 X7 [0 ^, Y' {( ]
  7. #ifdef __GNUC__4 i4 L4 E0 O/ K7 _' d2 N6 f
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    % s5 w3 r. l& G) u$ k, n+ @
  9.      set to 'Yes') calls __io_putchar() */
    ; O: e3 I5 i- t/ b$ K! y: o
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)3 Y- l' k6 _. A9 L; M
  11. #else
    ; J  \4 d* v9 C; `6 }
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)0 S: G1 K8 O; a
  13. #endif /* __GNUC__ */2 i! S9 P9 ?, u% \- w# U4 e
  14. PUTCHAR_PROTOTYPE
    # `9 h3 {3 j* y6 u' Q
  15. {
    / j* W; v1 v5 u1 k# t" f
  16.   /* Place your implementation of fputc here */
    ( u+ n/ S3 l5 _
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    9 t& @4 h! Z4 V& Y, t1 G
  18. ' H4 W& ?$ @9 q6 K
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);: s5 l. z+ P' p; L1 m/ N  Y! O
  20.         9 e$ G" m0 x/ K- V
  21.   return ch;
    ; z6 n7 l- V- n
  22. }
复制代码
+ j. }& y/ ^( j( {2 G( D
2.RTC时间获取函数
3 |% N% E% i% h. i/ d" v# g5 k5 z; D' e/ {
  1. /* USER CODE BEGIN PTD */4 f( \3 B9 o8 m# S8 T
  2. RTC_DateTypeDef sdatestructureget;' p& [6 W2 S  @7 z8 s* f
  3. RTC_TimeTypeDef stimestructureget;
    ' z+ b) ?) Y& ]" ~4 z# G0 y
  4. uint8_t aShowTime[16] = "hh:ms:ss";
    " J$ O2 O! `* L
  5. /* USER CODE END PTD */- f% w+ z; t* A% S) b
  6. ) T0 T" ]4 W) g& y) ^3 i+ I
  7. /* USER CODE BEGIN PD */
    1 x0 f/ m6 d8 C8 E$ p, f5 c; S
  8. static void RTC_TimeShow(uint8_t *showtime);
    4 i% _6 H3 V2 ]5 k( U
  9. /* USER CODE END PD */
    1 N  [' N: ?, X$ a
  10. ! Y9 I7 k( j" s2 Q, K0 y- h
  11. ) P2 o$ D2 ]1 H& n
  12. static void RTC_TimeShow(uint8_t *showtime)- K/ T& b, c; @1 Z8 ^8 i
  13. {
    ! `( v( K! X0 O3 I& P6 H

  14. : w' Y9 F! X# q: ~: y# z

  15. ; s: H% W1 Z1 y
  16.   /* Get the RTC current Time */- [, `9 J# K5 y% J1 P$ F4 c
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);4 P/ p( w. [. Y  e4 c3 _0 {
  18.   /* Get the RTC current Date */
    % }, _, o( U  P- N
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);6 A& P; K0 K$ Y0 q
  20.   /* Display time Format : hh:mm:ss */
    * l1 `: i: y7 H' U5 f5 X5 ?. A
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
    1 s, w2 P, }7 N/ ]
  22. }
复制代码

+ M8 ?9 Q1 V% j; p$ W! r3.standby进入函数4 n0 X- D8 h  F4 k1 \3 p
  1. /* USER CODE BEGIN PD */
    0 @9 @% I0 i8 n" D
  2. void Sys_Enter_Standby(void);( C3 J5 d8 }- e6 w$ A3 Q$ \1 f
  3. /* USER CODE END PD */
    - h  F! Y2 f' x! E
  4. & @4 C' L/ \% ]9 G; y
  5. void Sys_Enter_Standby(void)
    ' Y  M0 @) |( g" n  P
  6. {5 O0 [2 i3 m3 r3 e
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry
    - `# X/ u6 F/ h% F+ }
  8.   - Enable wakeup3 y( T: I2 X8 l; W+ d( }0 H$ v) A/ m
  9.   - Clear wake up pin flag depending in edge detection & pin level.
    " G7 w" q' t, [! z* \" z
  10.   - Enter the Standby mode.
    # R5 w. |7 N) [: R
  11.   */
    ' e% g  B8 x: W7 a+ P

  12. , g6 L2 \+ C1 ~) q9 i5 D
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */
    & }3 n7 H6 h$ Y
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发
    ; \$ y) j& O: d
  15.   HAL_PWREx_EnableInternalWakeUpLine();
    : t2 |! f2 R7 q8 L, g9 P) W
  16.   /* Clear all related wakeup flags*/
    6 }1 U9 w2 ?2 b
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    7 X5 P9 L, Q1 ]' m' C+ e9 ?
  18. ; i' O3 }" ?' A8 W
  19.   /* Enter the Standby mode */% M& Z9 W* Z$ m+ V9 w0 J
  20.   //HAL_PWR_EnterSTANDBYMode();
    & ?2 C" z6 ?! b& K
  21.         printf("enter Shutdown Mode!");: j8 B. P3 R7 J' R
  22.         HAL_PWREx_EnterSHUTDOWNMode();
    ( U* N, o0 v. b5 u/ J' z

  23. ( z, t5 N8 N, y1 g3 b
  24.   /* This code will never be reached! */
    3 e- D. i$ x* u# y" _' J4 I
  25. }
复制代码
7 _( v+ v' _$ ~. `
4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)" A9 y0 J* Q6 M  F" u
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
    " e' v: @* _0 y- N" j' {
  2. {5 s7 t- R7 S: r6 p' i* q
  3.   /* Prevent unused argument(s) compilation warning */
    1 T  L% ?* }( N& k; }
  4.   UNUSED(hrtc);
    2 b+ G/ M* R* H

  5. 8 t3 r: r5 W0 q5 F; S+ f8 F1 ~' M
  6.   /* NOTE : This function should not be modified, when the callback is needed,
    ( C" Z$ p& {0 B5 e% @! y
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file
      a" O6 p# X8 Q5 m, K+ y) P# `
  8.    */
    . v/ f  o) F3 s3 b5 }. @  `
  9. 8 ~1 L/ ^/ M2 N; x& T" A
  10.         flag =1;5 U* o! }) w; v* t, Y
  11. //        NVIC_SystemReset();
    + F5 S1 b% d. F* j* ^# m/ l4 Y
  12.         
    9 e+ E( a1 ~/ ~1 [1 i! o" w) j
  13. }
复制代码
" e, ~# \% d2 e% C& p/ \0 ]$ c( J
5.在main函数中5秒的时候进入低功耗模式
3 o3 p, r2 y* V4 @; v5 {* I  q
  1. /* USER CODE BEGIN 2 */7 n5 d4 h$ _; x' R# {
  2.         uint8_t sec=0;" ?4 y- V$ q5 Q+ }& R% f& s# z
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
    " @4 j5 x  r8 C6 z5 h) ~4 `3 r
  4.   {; g6 H, B0 ]) e6 m
  5.     /* Clear Standby flag */8 D4 u, ^; ]* I$ _
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    1 U) @4 o7 ~" l3 q8 D' B7 g
  7.                 printf("wake up from standby!");! F* N& s$ ?: y
  8.     /* Check and Clear the Wakeup flag */
    $ G$ ^( Q) l; I  W, p/ f- T9 M! A8 d
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
    % G) ]9 I! i. C( ^/ R
  10.     {
    , J" R1 i! ?  F  F
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);$ p, x) I' T' L5 |
  12.     }
    # v( r& [0 I, S  P
  13.                 4 L) o) y3 T3 y- i
  14.     /* Wait that user release the User push-button */
    / s: H: G( v1 b- W9 \' H- {6 @" l6 c
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}
    7 L; W/ ]0 e4 I, S! H

  16. - `& A2 m- i- E0 t% K
  17.   }% j$ ~! p# R; ?
  18. / |7 U# T8 L* k* ]2 I, y- T
  19. ' z" N7 o. |$ z" n  J
  20.   /* USER CODE END 2 */) I/ E3 N: \+ F8 {7 n
  21. 2 v; V" M: [1 P7 U7 ^/ {9 v& b
  22.   /* Infinite loop */
    , |5 O) {& {0 M+ n% \, W
  23.   /* USER CODE BEGIN WHILE *// \; X; E8 a" \* T/ S
  24.   while (1)  _1 r1 e% j- K; o3 Z
  25.   {
    : X% S: z" y% `; x$ _( f
  26.     /* USER CODE END WHILE */9 Y% ?- {0 ^/ A6 f4 T& M% c' ]/ J

  27. 8 J' C' p+ t5 q, J" ]& [* J
  28.     /* USER CODE BEGIN 3 */; Z1 f# ]! V8 t5 Q, K
  29.                 RTC_TimeShow(aShowTime);
    & u2 G3 y- `$ M' L( _$ u
  30.                 if(sec == 0)flag=0;
    6 E5 ]3 b% ~' O

  31. + R& i. F0 w0 ?) }: z) r
  32.                 if(sec == 5)Sys_Enter_Standby();
    + U2 {( u4 a. _9 K
  33.                 if(sec!=stimestructureget.Seconds)
    + O4 N" A. a& v# H; u- q7 f
  34.                 {' L3 I1 B# h$ e" U9 A# @/ F9 Q
  35.                         sec=stimestructureget.Seconds;; d+ w0 c# J/ V4 \7 x/ ^6 l
  36.                         printf("%s",(char *)aShowTime);
    ) ]( I/ D. y9 ]
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);8 g/ a# x1 [5 K4 a- _
  38.                 }
    & O4 L+ K# T6 z# p- s% f+ @! {
  39.   }
    ; ^" w+ i9 X" P. ]& _
  40.   /* USER CODE END 3 */
    # H7 `7 t( ~. F" N& }( f  y
  41. }
复制代码
! N- o+ j+ o  ^. \3 u
至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。: E& Y: Q3 s" W: _  J3 A* h
- d2 C8 C* b8 _  |/ O
附加 避免上电自动配置RTC时钟
8 H+ A( e( E- n& X. O5 |  a# r6 Z
  1. /* USER CODE BEGIN Check_RTC_BKUP */
    : e' b; Q/ Q' D9 f
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}
    ; N! P8 O' }  R: ~+ z
  3.         else{return;}
    + j4 L3 e! I* I4 X& n
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码
3 k- ^  Z( O2 H; Q; g# X
以上代码请添加于MX_RTC_Init(void)中
* i3 n. R/ h  a: v; b7 Z3 [+ h- p3 |$ w, ~% `6 `( g
2019051001272486.png
, j  |/ I- H& y0 R7 ~, d/ K% e

2 x$ V9 U  P2 ?1 K4 P% o项目文件, W  E1 A6 K; d: v6 F. m+ q
' ]& Z9 U/ u: {) v. W# o
20190510013203724.png

8 a" D& Z# g5 i! ?- Q6 C. T: g- z( h: d/ T, N

, ^' o# \2 x# \9 M3 v
赞 收藏 评论0 发布时间:2021-11-8 15:49

举报

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