请选择 进入手机版 | 继续访问电脑版

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

【经验分享】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。
  i4 @* m" @6 \  b0 j7 Z& Q6 s( j. ?* W0 ], h
首先配置时钟、UART、RTC和中断。) u  W+ J( O; K6 _9 _' B

7 v/ r' A1 Q5 a; e" [; `
20190510004029552.png
0 |! W. b+ z+ Q$ K4 ^
( z$ z0 Q& I; |$ h2 e
RCC选择外部晶振(shutdown 模式只能使用外部晶振)其他默认5 ~3 E" a1 q  w3 _2 x, y! `
+ ]5 X# o2 y$ F
20190510004154456.png
+ Z/ e$ i8 l. }- c% q
+ g" |' w3 J, ^) J5 a2 Z
SYS选择调试接口,和wakeup_pin2,STM32G0目前新线还是很多资源的7 @8 }* e1 O( r
5 B9 H  R, p! c0 `2 |0 k  `
20190510005141588.png
# o2 Q9 J3 t* ^; w0 [
3 n1 [, |; V% Q$ _+ d
设置RTC,填写相关初始化信息、开启ALARMA时间设定为开机后30秒,注意RTC_AlarmMask=RTC_AlarmMask_None;则为精确匹配,即闹钟不仅要求时分秒匹配还要匹配日期和星期,都匹配后触发闹钟中断)) w" m( P, B3 [: k) O, j
/ H- E  Y1 f/ w
20190510005211104.png

8 c& P% [- B8 [. P6 I3 r! l0 A0 v7 P6 X* i
设置串口5 U9 e; O# y7 I8 `: W5 [
; ]0 j$ N2 D9 [- |6 f
20190510005241164.png
0 b; s% i& B- K, q; P1 R  I5 F) U

) [# i( R# c9 d8 b% t- P打开中断入口6 [; q. |0 `3 j

4 A# i$ R1 [" a3 m
2019051000534771.png
: _# T, I+ e. T2 e/ F* z1 A. B& W2 C
+ ^- V, @% e" r& Z0 b5 T
20190510005358325.png

5 ^% d# ], s2 D# E, Y
) X2 B1 \+ z- L$ N- q4 M! f完成设置后点击生成代码创建工程) w( S2 D+ t# d  }. k
$ a& \; r: b# F3 L7 Q9 L$ I" @
1.首先喜闻乐见的printf函数# U* S( ?- b0 h- N
  1. /* USER CODE BEGIN Includes */
    ; s& T6 a+ |; R' A
  2. #include "stdio.h"" A  B. |% \0 W( {4 b
  3. /* USER CODE END Includes */
    , E, W) P; @, w) \

  4. # `' S+ j# d: y/ B

  5.   d5 K4 Y( f  b  |5 C% @
  6. 2 k5 K% F" ~- j7 u1 W; w
  7. #ifdef __GNUC__  U1 ]* E' N+ F! L
  8.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf8 r, g1 w: Q& h+ _! w
  9.      set to 'Yes') calls __io_putchar() */7 h! B/ Y+ _1 G* C0 R
  10.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    9 K- B+ z' ~: g3 P7 i
  11. #else$ [$ T) {1 i. o- l# V% r' F" `( m# N
  12.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)5 V# f5 M% h1 R. e0 i  o
  13. #endif /* __GNUC__ */* f# a% k. Z/ T8 {& B
  14. PUTCHAR_PROTOTYPE5 }. S6 g& m5 q1 F2 ?
  15. {
    8 L7 Q8 l3 w8 ^3 [- }8 V
  16.   /* Place your implementation of fputc here */2 c  P3 M& }0 q* x2 [. P- v
  17.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */. |' a+ m+ `; ?4 c

  18. * \' U: |* J3 m; X: g' l! _
  19.         HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);. |0 M1 @# F3 y$ f2 t
  20.         
    2 P( a# w  @( g9 j! @8 ?
  21.   return ch;" s0 Q. @: n# L, }( G, \5 d2 A) d
  22. }
复制代码
& t- _6 D. k) U  l9 r9 \
2.RTC时间获取函数
# W. I% ^- d6 X2 M* l3 Z1 h3 o7 w: Q
  1. /* USER CODE BEGIN PTD */
    ' Y  D0 i' d& d6 G6 `
  2. RTC_DateTypeDef sdatestructureget;- K* O' p0 {5 }% ^# L# D) X
  3. RTC_TimeTypeDef stimestructureget;. L# L- t, P# ~/ c# b4 G
  4. uint8_t aShowTime[16] = "hh:ms:ss";
    5 L7 `/ [$ a; O
  5. /* USER CODE END PTD */
    6 j! i! {! s2 p+ e
  6. & T7 o' C; B4 i& R% c1 L
  7. /* USER CODE BEGIN PD */' l# y9 E/ p: {4 b
  8. static void RTC_TimeShow(uint8_t *showtime);
    4 ~* l) y7 G, Y. y* P6 K
  9. /* USER CODE END PD */
    3 A$ G* c( Z& e2 _
  10. * ?( @" c9 w9 p* j$ h

  11. 9 B' o/ P. J* `
  12. static void RTC_TimeShow(uint8_t *showtime)
    7 h! k) T3 S  {' U% H" h1 o
  13. {
    * Z' d+ g! H4 I( e" ~. [
  14. , Y5 q! b1 R& u/ V. i
  15. 1 g- U# W; Z; ~6 P% z8 z
  16.   /* Get the RTC current Time */, n$ v, R8 B+ t8 U" j: r  ^- c. U
  17.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);  x' _2 r3 A8 V, f: L6 _% S4 u$ i
  18.   /* Get the RTC current Date */
    # d) i" p1 }* |$ d6 Y5 D
  19.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
    * g3 A. {8 n) r5 H; d, w- B
  20.   /* Display time Format : hh:mm:ss */
    ; Q- }( h; y3 K- R  \0 w+ S7 d
  21.   sprintf((char *)showtime, "%02d:%02d:%02d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
    / o  i* W+ @5 o/ n+ a- {( _
  22. }
复制代码

" V7 m& H/ s) S% I1 f3.standby进入函数0 k- D' w- t' D: Z# O3 E
  1. /* USER CODE BEGIN PD */: y3 K" s$ e% X! Z
  2. void Sys_Enter_Standby(void);) N/ {* U8 C0 b" j) l" J0 q7 D
  3. /* USER CODE END PD */
    & q( k4 m8 i+ ~# k
  4. 2 f: ^# u) O$ [6 s( S
  5. void Sys_Enter_Standby(void)
    7 L$ m; ]/ }  W% H, U: ?; T3 H- k
  6. {) Y/ u9 ~/ |7 @9 m
  7.   /* The Following Wakeup sequence is highly recommended prior to Standby mode entry9 |" Z+ L. }2 f; z- k7 q+ E, g
  8.   - Enable wakeup
    7 ?1 b* ^  Q3 p8 X5 k
  9.   - Clear wake up pin flag depending in edge detection & pin level.
    # e1 [; G# a5 Z( L9 h2 Z
  10.   - Enter the Standby mode.
    2 I1 H% F  U  q  x/ r
  11.   */
    3 @, p2 A3 |% M/ ^2 Z* D
  12. ! z( f) s; {5 G
  13.   /* Enable WakeUp Pin PWR_WAKEUP_PIN2 connected to PC.13 */
    , }( N$ d7 p9 T. a+ l0 z' D
  14.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);//上升沿触发- ]' `- s. }0 u# Y8 n
  15.   HAL_PWREx_EnableInternalWakeUpLine();
    ' ]5 T9 D# o) d
  16.   /* Clear all related wakeup flags*/
    , f7 f) E/ Y. Z' D
  17.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    , A( f: b6 K9 r8 |' D/ O, ^, u" |5 a" ?& x

  18. : h' Y8 I" U# _. M! u! A
  19.   /* Enter the Standby mode */
    3 N  E  d/ c4 |" z5 Q; e
  20.   //HAL_PWR_EnterSTANDBYMode();
    6 j( D3 p* O$ g( Q; t% R; ~3 i
  21.         printf("enter Shutdown Mode!");
    2 l0 t' c! o% K6 H' a
  22.         HAL_PWREx_EnterSHUTDOWNMode();
    9 @# f& [& s0 g) G% J2 b
  23. . ]$ `& V: F( O- u3 j' w! Z
  24.   /* This code will never be reached! */
    " ~3 D2 [; a# {) y  m
  25. }
复制代码

( \  ?2 i1 ]' X1 t! \4.ALarmA中断回调函数 NVIC_SystemReset()用于standby触发AlarmA时间后与wake_pin触发系统自复位不同进入rtc中断后无法复位问题(我解决不了就软复位)
0 [6 p9 F% S' _4 o+ ]3 a6 O% `
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc), M0 H* q( u' {( y' X2 m, w7 K
  2. {
    0 ?) B. G% e3 w) f1 M7 ~) E
  3.   /* Prevent unused argument(s) compilation warning */. N; m. c  D0 [8 F& v
  4.   UNUSED(hrtc);! l0 x! o1 b7 |( d" U
  5. 9 `4 z6 B3 D, A8 Z) i! M/ [; m0 A
  6.   /* NOTE : This function should not be modified, when the callback is needed,
      \! x% c2 \, o/ f8 S
  7.             the HAL_RTC_AlarmAEventCallback could be implemented in the user file/ j& X% q) O( r
  8.    */
    : w- x5 N2 P) n3 b% A
  9. , o5 j+ w* S# {: M4 f4 e; |9 d& c
  10.         flag =1;, X% u  S' x1 o: l
  11. //        NVIC_SystemReset();
    1 _9 M7 i! f1 R1 E! c+ t7 W2 J! u
  12.         
    4 Z" T3 d- F1 U" n
  13. }
复制代码
  ^) K1 T, ~# H% [
5.在main函数中5秒的时候进入低功耗模式
# d* k; I1 x, y) P* w2 w6 N
  1. /* USER CODE BEGIN 2 */
    9 j( C1 t9 k, C' U
  2.         uint8_t sec=0;+ f' t4 L* \3 W
  3.         if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
    : S" \2 I; g2 |9 u
  4.   {
    $ p; \, p) x1 i. P
  5.     /* Clear Standby flag */$ `$ }# D! y+ Y: ~4 e& L$ ^
  6.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);& X: c  H' D: H( x
  7.                 printf("wake up from standby!");6 j0 R  x2 ?/ \/ h' ]- ]' e5 m
  8.     /* Check and Clear the Wakeup flag */
    ! o1 _" R3 Y0 |0 I
  9.     if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
    ! Z* d3 G3 Q3 H1 o5 N$ F& s
  10.     {
    - ^( `" D" F. W0 s& ?8 v1 q
  11.       __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
    : L+ ]! @0 P" t7 l3 Y% i
  12.     }
    " f- X* a4 \& P% G1 s+ c" u# V! Y% o! T
  13.                
    ' K& Z# C: e' c: D, T& W3 `! a
  14.     /* Wait that user release the User push-button */
    ) B, k! s! j! Q
  15.      while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET){}
      i7 ^- K/ L0 p6 s! H4 T
  16. : h9 e. C2 n- e  |" y' r# \3 b
  17.   }, [7 r1 o+ w) M. o8 g! y
  18. - U" g9 p2 x/ b% @9 L1 Y! A, h
  19. 3 g8 M0 I8 j/ X* k, G& U& y
  20.   /* USER CODE END 2 */
    + @& Y+ B# G& K; H5 w% `9 k7 j& n) K

  21. : ~) o- x6 `" E9 U" I
  22.   /* Infinite loop */$ N9 O' g8 g7 c' A* p2 m
  23.   /* USER CODE BEGIN WHILE */% d# c: D, S. w
  24.   while (1)
      u6 w; S6 w5 L
  25.   {/ E; t5 ^; `# C$ C7 L
  26.     /* USER CODE END WHILE */
    9 G" Z7 V! G) p/ g4 o) `; Y
  27. / I: R  z$ a9 C3 g0 i+ J4 [" b
  28.     /* USER CODE BEGIN 3 */
    % {; {9 B# ^: E! b
  29.                 RTC_TimeShow(aShowTime);
    9 W* C) E9 [  g+ U5 o
  30.                 if(sec == 0)flag=0;
      R: Z+ l7 h! g6 W
  31. * l, F" ?2 f' m9 m% e( O3 c. ~
  32.                 if(sec == 5)Sys_Enter_Standby();
    ' R" d" Z7 l7 ^2 U6 j% Z/ N
  33.                 if(sec!=stimestructureget.Seconds)
    1 t! S9 s5 C* L, v
  34.                 {! S0 @$ ]/ Q# `2 O: \8 n2 l
  35.                         sec=stimestructureget.Seconds;
    1 h) ?8 \- ?; ]6 w1 S
  36.                         printf("%s",(char *)aShowTime);6 N8 ?9 C0 Y/ s, F- `
  37.                         if(flag) HAL_GPIO_TogglePin(LD4_GPIO_Port,LD4_Pin);
    1 D; o: n) \& J- y0 z  I
  38.                 }
    # X6 z" J7 g& V- w3 n
  39.   }
    : I9 K5 q9 p  T2 U$ ^, |
  40.   /* USER CODE END 3 */
    / c' v; S5 X% |, g0 u3 ^  h% H/ N
  41. }
复制代码

: g* L" W% L& f# m! N6 _1 o. p; n0 x9 m至此STM32G071关于低功耗模式的进入与退出已经可以实际使用,大家可以参考,实际使用稍作调整。
' E4 U3 @2 ^# \3 P- T
% m) K, M+ Q, [: Z% C附加 避免上电自动配置RTC时钟" \: d8 _" o& q: N" Z5 W! V
  1. /* USER CODE BEGIN Check_RTC_BKUP */
    # s  N0 c! |+ I: Y% \
  2.         if (__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_INITS) == 0x00u){}2 C) U( J# N- c: y1 H  N' e
  3.         else{return;}
    + P# ^' I1 O/ }8 O3 s
  4.   /* USER CODE END Check_RTC_BKUP */
复制代码

7 C4 ]; j- B3 ~& D以上代码请添加于MX_RTC_Init(void)中" n/ o# Q- f6 M; f& `

2 }) V8 X5 v0 |  b3 W. t
2019051001272486.png

7 c* b" q; T" x# ?! K) b' {3 c. ^! z. r: Z$ q9 u, r* I. D" C
项目文件. p4 T, j" l" A# B

- q) X" }3 e, F* p' W3 z, \& h
20190510013203724.png
4 d- v# l9 o# A7 `1 `
4 M5 \2 m' ~; Z

' K& E2 g$ k- G* n* U
收藏 评论0 发布时间:2021-11-8 15:49

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版