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

ST线下培训(05-23成都站)STM32L476低功耗设计(三)

[复制链接]
wolfgang 发布时间:2017-7-5 22:53
& y0 C" m% P+ m! S. i+ |4 z
ST线下培训(05-23成都站)STM32L476低功耗设计(三)   

% `6 @5 q3 o2 ]' t0 C+ O
——进入Stop2模式,延时5秒后唤醒
$ T5 _( Z/ v8 X2 ]& ]

( p" i2 {; E7 T) K0 f

  S( Y; H) ~; u
一、实验开始之前
    上一章节次实验实现的是进入低功耗后测得的电流值,但在要在实际应用中,只能进入低功耗是不够的。需要能进入低功耗后根据实际需要和应用场景实现频率、电源的恢复,能恢复到进入低功耗前的处理能力。本章就针对进入Stop2模式 后的经过RTC定时五秒后恢复进行数据测量。
( N6 x: A9 c$ \+ R( |+ A
二、实验过程1、实验前探索
1.1 RTC时钟源选择
  在正式实验前,将功能树上的是RTC功能打开,并在时钟树上查看RTC时钟源频率。
8 L; L) L# z' g0 L

; [3 d+ Q  D  T- p0 v& I
01.jpg
0 [$ j. Z$ X' |# P- R' Y# ~  O

, k8 u7 p% _1 y- R3 Y* y* P4 m
02.jpg

& G* b# w+ Z4 [5 `. U# u
" ?8 c& a+ p- a- t5 z, s
   从时钟数可以看到RTC时钟频率使用的是LSI RC的32KHz的频率。当然也能选择LSE或者HSE的RTC分频后的时钟作为RTC时钟源,进入除Shutdown模式外的低功耗(因实验中板卡为Nucleo L476RG 缺少LSE,无法对Shutdown模式进行唤醒,需要另外焊接LSE 的元器件后方可进行实验),将时钟源统一为LSI 的RC,具体的产品环境根据实际需要选择时钟源。
1.2 时钟源相关设置
03.jpg
. e/ M# r- c' D
  设置唤醒时钟为 32K的16分频,频率为2K,唤醒定为5秒后,这里设置5*2K=10K次。

! b0 w) q" j8 w+ _* H2 }
设置唤醒中断使能。
04.jpg
1.3 LSI时钟功耗
将LSI、RTC始终设置后,因增加了设备,会增加进入功耗时的功耗值,分别测试打开LSI、RTC后的功耗值如下:
RUN:              15mA;(外设功能活动)
SHUTDOWN:      0.09uA;(外设功能停止)
STANDBY:       0.68uA;(外设功能停止)
STOP2:         2.13uA;(外设功能停止)
LPSLEEP2MHz:     87uA(外设功能活动);
) d7 Y' z9 [7 f7 X# D
2、实验步骤
2.1 Stop2 模式使用RTC计数5秒后唤醒
2.1.1 唤醒方式LSI+ RTC
    进入Stop2模式后,除LSI、LSE之外的所有时钟都将关闭;
    触发唤醒的事件有:任意一线EXTI(已配置的EXTI寄存器)特定外设事件。
    唤醒后的系统时钟有两种情况:
       1、STOPWUCK=0时为进入Stop模式前的MSI频率;
       2、RCC_CFGR寄存器中STOPWUCK=1时为HSI16;
进入Stop2模式前,设置好低功耗模式的时钟:
  1. void Low_SystemClock_Config(void){
    % C/ d. i8 C0 F/ |
  2.          RCC_OscInitTypeDef    RCC_OscInitStruct;7 f. z9 z& J3 C  |* t0 p
  3.          RCC_PeriphCLKInitTypeDef    PeriphClkInit;" q4 N1 G$ {8 ~
  4.          RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSI;
    0 H. a$ J# U$ M4 ~" V
  5.          RCC_OscInitStruct.LSIState    = RCC_LSI_ON;
    & Y$ A8 D) C" J. B7 d! Z+ D
  6.      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    : _, k' y* W! Y, i8 |
  7.      {* j- C& P" Y. z
  8.        _Error_Handler(__FILE__, __LINE__);
    & {/ f0 Q+ ]. y
  9.      }
复制代码
  1. PeriphClkInit.PeriphClockSelection    = RCC_PERIPHCLK_RTC;
    + K# f& j5 \3 O
  2.          PeriphClkInit.RTCClockSelection    = RCC_RTCCLKSOURCE_LSI; ! ]5 x8 D/ l% W0 x4 R
  3.          if    (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)3 L  ?& C, m) ^" P2 _" t& I) k
  4.      {+ h9 d% f% X9 g: x! K
  5.        _Error_Handler(__FILE__, __LINE__);
    * E# I7 U6 d5 Q& z  a
  6.      }/ P6 P* _$ U. }' Y

  7. 5 j9 i6 c$ f2 ?
  8.      /**Configure the main internal regulator output voltage+ ]% F% j; Q% A. t0 a% d
  9.      M# \( M0 q  C0 M% ?2 q" d
  10.      */8 }+ z# a5 V: M. S. [
  11.      if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) !=    HAL_OK)$ \. t- b0 r( P2 v  ]
  12.      {3 t. i) g5 a" ]8 `, x# f; }
  13.        _Error_Handler(__FILE__, __LINE__);- V+ }6 V% s& }9 l3 `" Z4 M1 @4 X
  14.      } & o) b5 |, e3 Q+ ], |7 N+ D
  15. }
复制代码

. f. O* D* |  e+ k# H& d. q8 A: S1 U- k' Y. \' ^* m( l
RTC初始化,过去早的初始化RTC,增加正常工作时的功耗,若需要RTC在项目全生命周期工作的情况除外。
  1. tatic void MX_RTC_Init(void), }3 H5 ~( d3 y& _- U
  2. {+ T5 E9 y& H# f% ~
  3.      RTC_TimeTypeDef sTime;
    & `; f8 C8 T6 a3 u: _
  4.      RTC_DateTypeDef sDate;
    ) j+ Y# w6 g1 b9 r6 F# |: C

  5. ( H. j$ q" g  R% e& b6 O. @% U
  6.      /**Initialize RTC Only9 M' l+ M/ V0 w4 N' A
  7.       */
    8 c. J0 F# l& U9 r+ a4 a1 K
  8.      hrtc.Instance = RTC;( m7 _5 h5 _2 N1 Q6 W  ?
  9.      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
    & ]' {% `: y- m( E
  10.      hrtc.Init.AsynchPrediv = 127;
    ; }/ f9 m; {' ]! q4 Q
  11.      hrtc.Init.SynchPrediv = 255;# v3 }8 J" u, K/ F. M. k
  12.      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;3 y6 V: E/ ^' C( h( I3 x, a0 f% C, r
  13.      hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;3 g# k2 [- H( Z3 C; R; E8 n( \
  14.      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;  \" B1 v& j/ z' b
  15.      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
    6 ]4 u0 z, C* A, P  R. \% N
  16.      if (HAL_RTC_Init(&hrtc) != HAL_OK)- ~$ Z( d. y; x& T* t7 U
  17.      {9 ^$ {  ?, k/ j9 c* K6 p% t6 c" d; I
  18.        _Error_Handler(__FILE__, __LINE__);
    & ^3 ]+ a9 E7 }! i) S
  19.      }
复制代码
  1. /**Initialize RTC and set the Time and Date
    / @+ I$ ^1 @: J0 v# e- h
  2.    
    $ e" T% Z8 p2 J, S1 d' X6 {
  3.       */( Z+ t. W) h" \# Z0 i2 l4 `
  4.      if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
    % {5 H( H$ K; w# |5 i
  5.      sTime.Hours = 0x0;) c( C. i" A. K: h9 U) Q
  6.      sTime.Minutes = 0x0;
    3 Z) X, b  f! k6 A
  7.      sTime.Seconds = 0x0;
    % f) Q% G/ e7 T9 e( H$ U
  8.      sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    : R6 S3 L% |& M3 V2 l
  9.      sTime.StoreOperation = RTC_STOREOPERATION_RESET;3 j' }5 j0 c. @; A% }
  10.      if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) !=    HAL_OK); x% y/ u. w  O6 Y+ M
  11.      {
    ! e  L$ T' m0 \0 M$ x; a0 A0 B
  12.        _Error_Handler(__FILE__, __LINE__);
      D! ], @& D" e+ o2 ]8 H
  13.      }2 w6 f7 {5 a* F7 P3 ~7 j( R

  14.   r( `) c- `6 v' L% ^4 ^; M8 h
  15.      sDate.WeekDay = RTC_WEEKDAY_MONDAY;, Y/ x8 t6 j; y1 ~! \: d9 M) _
  16.      sDate.Month = RTC_MONTH_JANUARY;( o( f+ l1 {8 V/ C* K5 j
  17.      sDate.Date = 0x1;  |! @6 G# j/ F
  18.      sDate.Year = 0x0;
    " r7 v* N7 ^+ _  C# h" b5 g' T7 W

  19. 8 }# n3 z8 h; ]% c
  20.      if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) !=    HAL_OK). x3 z. {3 C) {- T: U8 `
  21.      {
    , m; ?# g$ S2 A7 L. w2 o
  22.        _Error_Handler(__FILE__, __LINE__);0 c' O* c4 w& |  L
  23.      }
    0 ~& X3 M6 K, O
  24. " R8 f1 A% A; d% R! T# o' B
  25.        HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
    5 }8 [2 z' {8 ~7 D$ [
  26.      } * S, }  w0 w: l
  27. }
复制代码

' U1 d4 x2 G9 `# y8 A& {$ |7 x1 G( N8 j
设置RTC从STOP模式唤醒后的系统时钟以及事件唤醒中断:
  1. HAL_RCCEx_WakeUpStopCLKConfig(RCC_STOP_WAKEUPCLOCK_HSI);% z' S- z$ @4 U& \$ k6 M9 U6 e! D
  2. HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,    20480, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
复制代码
0 K: {( I/ ^0 e9 J4 s$ ^$ o( Q
随后就能进入STOP2模式了,直接调用Test_Stop2()。
8 l/ i) V8 ]/ z/ A/ ]2 ~9 ?- h$ w$ w( p- N5 c' Q$ [
在进入STOP2模式后, 经历RTC计数到达唤醒设定的延时时间,及触发RTC_WKUP中断,
在HAL生成的中断函数里调用了唤醒中断函数, HAL_RTCEx_WakeUpTimerIRQHandler(xxxx),
其中的HAL_RTCEx_WakeUpTimerEventCallback()回调函数,是需要根据开发者自己定义的,  J0 E  N/ Z1 c

: c; e( [; ]+ p% z6 B6 d% S
  E: Y1 B1 s! o& x! V8 z  G
  1. void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {; o' B( o8 c- i: ?- F5 B' L
  2.         WakeUpState=1;1 L! ]/ _- c" S% ^
  3. }1 U9 x" U& s- K7 U* j2 ?' U: w: u
复制代码
考虑到唤醒中断优先级,这里只标记唤醒状态,具体唤醒后的操作交由主循环中的内容只执行:
  1. ........
    $ q. M  `; F( d' ?, d/ v
  2.      if (WakeUpState){
    * ?0 k" t& @9 n& E, P
  3.                   WakeUpState=0;8 g5 T# g# I, ?. ^' Q5 p5 c
  4.           //禁用RTC 定时器WakeUP,避免再次出发唤醒
    . Z7 {; w0 R8 o
  5.                   HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);, Q# ?* ?  Y, g4 b
  6.                   //初始化变量及引脚功能, t' r. R, O4 y4 b# W" a
  7.                   EXTI_State = DISABLE;* _: I/ f5 L# }1 d+ b: o" R
  8.                 , G; W& ^0 b5 c. S3 k6 C. d
  9.       //HAL_Init();6 E6 `6 h5 i8 L  D- b
  10.       SystemClock_Config();
    % A0 ]+ n2 H, X: Z6 Z0 v& I. P4 f
  11.       MX_GPIO_Init();
    . f4 f' \" f6 g
  12.       MX_USART2_UART_Init();* W. M( v* u9 P  e6 E% S/ m
  13.       printf("\n\rWake Up From RTC  \n\r");5 x) ?! r1 `8 Q
  14.           }! U( d9 W1 }+ L0 @2 p0 w+ |$ m
  15. ........
    3 p4 o  E7 M& N! i
复制代码
至此,RTC 唤醒的功能就完整了

/ I' t3 V4 c& h; t4 bSTOP2 状态定时5秒唤醒动图:
6 ^! P4 G9 O; w STOP2 停止五秒唤醒_20170706230845.gif
' H+ Z  j- E) X% R
+ u- s$ ~- I/ s9 S8 e8 }: i
- t6 l$ q  l1 _5 v& v- O" z0 n& a+ O9 c0 x
6 s" o7 P" ?. L) V( o& F
代码参考前一章节的内容作了适当调整,见附件Main.rar- Z% f! t1 o2 V3 ~" g* j
  I% l, j3 F0 \8 `; J/ H5 E
main.rar (6.04 KB, 下载次数: 127)
赞 收藏 1 评论7 发布时间:2017-7-5 22:53

举报

7个回答
wolfgang 回答时间:2017-7-5 23:09:30
最近工作比较忙,再加上电脑重装系统,这篇文章等得有些久了。。。。
Paderboy 回答时间:2017-7-6 08:43:26
多谢分享。。
zero99 回答时间:2017-7-6 09:59:27
哇哦,楼主又有更新了,过来支持下
7 x3 l" z6 d* {; |1 `3 m5 H, B5 F9 \% g) V6 {$ X9 h# M
帮楼主把代码部分格式改了下,下次也可以这样操作哦6 z6 ?$ l' N; j: |$ _* F- N$ `! r  j
1212.png
8 O) ^+ \8 I( h: }: L* q8 {0 v
wolfgang 回答时间:2017-7-6 10:25:01
zero99 发表于 2017-7-6 09:59' B% M5 t0 i8 v% s4 r1 J
哇哦,楼主又有更新了,过来支持下
0 t' R; H2 w* `; H6 r6 v0 S. n1 w3 J8 D. b# \
帮楼主把代码部分格式改了下,下次也可以这样操作哦

& y( B: t: ^; d5 n. U4 |好,谢谢~~
epochal 回答时间:2017-7-6 11:15:59
谢谢分享!
wolfgang 回答时间:2017-7-6 22:13:54
唤醒的代码说明补全了
世事莫太贪-255746 回答时间:2020-1-9 10:08:31
谢谢分享

所属标签

相似技术帖

官网相关资源

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