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

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

[复制链接]
wolfgang 发布时间:2017-7-5 22:53
2 E! ]6 f0 C6 `. D1 ~
ST线下培训(05-23成都站)STM32L476低功耗设计(三)   
7 h, J- I$ k6 H: e
——进入Stop2模式,延时5秒后唤醒

) U) R7 d. z' [) `( w/ L& \9 R4 }
5 y6 M3 T# Q8 C* w$ L) o
' o) K# a8 b4 b! Q0 g
一、实验开始之前
    上一章节次实验实现的是进入低功耗后测得的电流值,但在要在实际应用中,只能进入低功耗是不够的。需要能进入低功耗后根据实际需要和应用场景实现频率、电源的恢复,能恢复到进入低功耗前的处理能力。本章就针对进入Stop2模式 后的经过RTC定时五秒后恢复进行数据测量。

. o% k0 I) |# ^  c二、实验过程1、实验前探索
1.1 RTC时钟源选择
  在正式实验前,将功能树上的是RTC功能打开,并在时钟树上查看RTC时钟源频率。

7 y6 [. T( b6 o7 {5 w9 i# O) G4 O% p( j
01.jpg

$ K* P5 c  V9 J/ g  ?* A
1 Y& K9 W8 a' z) v! ~, c( I( y
02.jpg

/ X- M% F2 b# m( n. w+ e+ p+ e' _: e$ E
   从时钟数可以看到RTC时钟频率使用的是LSI RC的32KHz的频率。当然也能选择LSE或者HSE的RTC分频后的时钟作为RTC时钟源,进入除Shutdown模式外的低功耗(因实验中板卡为Nucleo L476RG 缺少LSE,无法对Shutdown模式进行唤醒,需要另外焊接LSE 的元器件后方可进行实验),将时钟源统一为LSI 的RC,具体的产品环境根据实际需要选择时钟源。
1.2 时钟源相关设置
03.jpg
* A6 o9 G  A/ j" r9 W
  设置唤醒时钟为 32K的16分频,频率为2K,唤醒定为5秒后,这里设置5*2K=10K次。
0 p! q* ]# r. p! y# U0 ?9 U
设置唤醒中断使能。
04.jpg
1.3 LSI时钟功耗
将LSI、RTC始终设置后,因增加了设备,会增加进入功耗时的功耗值,分别测试打开LSI、RTC后的功耗值如下:
RUN:              15mA;(外设功能活动)
SHUTDOWN:      0.09uA;(外设功能停止)
STANDBY:       0.68uA;(外设功能停止)
STOP2:         2.13uA;(外设功能停止)
LPSLEEP2MHz:     87uA(外设功能活动);

' g" U! C" ?4 g. o6 X
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){1 }5 w+ I; m! n" m  |* b
  2.          RCC_OscInitTypeDef    RCC_OscInitStruct;
    ( G5 w4 y3 p: }. [! }9 j9 a
  3.          RCC_PeriphCLKInitTypeDef    PeriphClkInit;' C- v8 z8 |/ _3 d) m7 N4 O3 ?
  4.          RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSI;
    6 e# {! W' j# A* C0 E4 C
  5.          RCC_OscInitStruct.LSIState    = RCC_LSI_ON;
    ) s. j3 T2 [8 q6 `
  6.      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    * q% ]( O, L; U# M8 J5 j
  7.      {9 @9 X0 A# M) N% `" O! x0 O
  8.        _Error_Handler(__FILE__, __LINE__);, S7 X$ ]0 E: o9 O- |
  9.      }
复制代码
  1. PeriphClkInit.PeriphClockSelection    = RCC_PERIPHCLK_RTC;. ~- H! e% G$ v/ d
  2.          PeriphClkInit.RTCClockSelection    = RCC_RTCCLKSOURCE_LSI;
    6 L" k: }4 m$ _: U2 y
  3.          if    (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    9 s( O6 y: S# p5 ?$ a# W
  4.      {
    ! A: {) t: x2 s( q! S( j1 g# T
  5.        _Error_Handler(__FILE__, __LINE__);- Z; l3 Y3 u4 O* p+ H* ~
  6.      }, l% v- D) p5 ]0 c6 @5 c
  7. ( |0 \/ W' p& @' r" t: p
  8.      /**Configure the main internal regulator output voltage
    & Y, L" r. ^# L* j2 Y
  9.    8 w: u8 t$ ~# ^$ c) U* Y5 I5 c
  10.      */1 u* ]4 g& z0 x: z5 `4 P4 l. ~- h
  11.      if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) !=    HAL_OK)  q4 z; U6 {& c. Q6 G; S" U1 z
  12.      {2 D7 C7 K% K) t& j+ l. R  f
  13.        _Error_Handler(__FILE__, __LINE__);3 K% l" b: p, J* V! r
  14.      }
    . ]7 k; f- Q7 P* I% ~, ]
  15. }
复制代码
) w' @; K9 x% ^9 F
, A: b: e. G. R
RTC初始化,过去早的初始化RTC,增加正常工作时的功耗,若需要RTC在项目全生命周期工作的情况除外。
  1. tatic void MX_RTC_Init(void)2 T* \5 D$ s. u- d; E' A
  2. {
    0 d4 h+ p9 z! k/ K) C/ L  b, y2 N
  3.      RTC_TimeTypeDef sTime;' Y" {- ^7 `7 n
  4.      RTC_DateTypeDef sDate;3 D0 \; x, R3 ^% }4 k
  5. 4 @8 f4 N/ H' k# z% v. U  a8 [
  6.      /**Initialize RTC Only
    0 p3 y  s  v9 e9 m$ x
  7.       */0 a! z" G  u) N; h6 _1 c7 @
  8.      hrtc.Instance = RTC;
    % y  O. B3 G# L0 M- z  @1 I& Q
  9.      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
    2 a6 \/ R5 t1 E0 H4 S4 R
  10.      hrtc.Init.AsynchPrediv = 127;
    3 S' N: k0 ^. G# U) V, y9 t
  11.      hrtc.Init.SynchPrediv = 255;
    + w: v9 s& j9 q" M/ Q
  12.      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;3 @+ L; Z( F( q8 |9 D" H, a8 Q! M
  13.      hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
    : E: K2 R( x- e" t
  14.      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;6 o' A3 L7 @0 n; l; Q2 j
  15.      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;8 x/ Y; [* G$ |3 I7 V6 F
  16.      if (HAL_RTC_Init(&hrtc) != HAL_OK)* T( v7 K6 c/ R! ]1 I! L( X0 E) ^
  17.      {: C' u; ?$ s1 t9 I6 h/ Q
  18.        _Error_Handler(__FILE__, __LINE__);
    $ Q  b8 W; _& ?; F
  19.      }
复制代码
  1. /**Initialize RTC and set the Time and Date! I, K" X5 P# R; J2 m" Q- W7 r
  2.    
    & F& i, @% N$ w  i8 L
  3.       */
    1 T$ ]- S  o1 w9 c
  4.      if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){/ X1 o" f! j, G; w' y
  5.      sTime.Hours = 0x0;
    2 r8 Q/ [* O& G4 k" N$ Q) q4 `
  6.      sTime.Minutes = 0x0;: ]0 I; N. O& ]
  7.      sTime.Seconds = 0x0;
    ( B, m( R# n) s: i
  8.      sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;6 i9 ^" s$ a; i( j$ R
  9.      sTime.StoreOperation = RTC_STOREOPERATION_RESET;6 [/ c! w! R: W+ f
  10.      if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) !=    HAL_OK)
    7 _7 [! v" m  b  O5 L
  11.      {
    0 I3 B+ q; M# x1 F' {
  12.        _Error_Handler(__FILE__, __LINE__);0 _9 r  T. `# A8 ^* n
  13.      }
    7 y  M( N% P. T

  14. ! b1 X3 w% N: Z$ B  R/ m
  15.      sDate.WeekDay = RTC_WEEKDAY_MONDAY;! d' a" {' L  }  ?" L
  16.      sDate.Month = RTC_MONTH_JANUARY;
      H& E$ M, ?" m( m' g
  17.      sDate.Date = 0x1;8 K6 ]2 a6 s$ e% u6 D
  18.      sDate.Year = 0x0;
    7 L- x" N% n$ I8 {: R* ]2 `
  19. , w$ x% I# u9 k; Z4 C" y  A! G
  20.      if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) !=    HAL_OK)! f" _9 `* E6 Y/ l# ]
  21.      {& c$ A) y( n: n3 q) B4 a
  22.        _Error_Handler(__FILE__, __LINE__);' s( u5 R& l0 `) z! e: s
  23.      }
    - ^1 v8 `7 Y4 O5 U- y. r

  24. ' I! s7 \1 p+ |, Y1 i' Z
  25.        HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
    / i9 q- w  q& d. @  y4 Z" l8 y
  26.      } / q+ r% p# n" o0 Y8 ?+ j/ @
  27. }
复制代码

5 q1 b9 [' n0 }) M: K7 E6 Q3 i& i5 E/ j+ P! i
设置RTC从STOP模式唤醒后的系统时钟以及事件唤醒中断:
  1. HAL_RCCEx_WakeUpStopCLKConfig(RCC_STOP_WAKEUPCLOCK_HSI);' M2 A! q- Y; J" J* o
  2. HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,    20480, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
复制代码
1 ]7 m" b- A  z. n  c
随后就能进入STOP2模式了,直接调用Test_Stop2()。
! ?1 e- h, y! }. @2 Z; t$ L. z9 Y
在进入STOP2模式后, 经历RTC计数到达唤醒设定的延时时间,及触发RTC_WKUP中断,
在HAL生成的中断函数里调用了唤醒中断函数, HAL_RTCEx_WakeUpTimerIRQHandler(xxxx),
其中的HAL_RTCEx_WakeUpTimerEventCallback()回调函数,是需要根据开发者自己定义的,; V0 y- P: E9 w$ y4 _

0 t. ?2 d& C2 h: X1 |; y; C5 n# Q
- {. @0 B. ~, X) S5 A
  1. void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
    ! \9 L: D2 ^0 \: y, D5 \+ O
  2.         WakeUpState=1;
    0 n: C; f2 ?- S1 q. N, s. m
  3. }7 D' }# U9 p, v) H/ W# r
复制代码
考虑到唤醒中断优先级,这里只标记唤醒状态,具体唤醒后的操作交由主循环中的内容只执行:
  1. ........" e+ q! i2 |6 Q) S
  2.      if (WakeUpState){& g* n  N4 ^7 V" s6 ?5 O# v  c
  3.                   WakeUpState=0;
    ( _; o' o# E* _0 V! @
  4.           //禁用RTC 定时器WakeUP,避免再次出发唤醒
    ! \) t8 _% v- }) W' y2 ]; c% s
  5.                   HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);' ~- X7 ~1 j5 B8 V9 R+ ~
  6.                   //初始化变量及引脚功能) X) u* s  a* L/ T. t
  7.                   EXTI_State = DISABLE;- q" w- n+ z) ]) P, _+ ^  c: g
  8.                
    $ j& x8 t$ C  d3 Z+ N
  9.       //HAL_Init();
    " E6 T: m6 H" D) t3 R* h
  10.       SystemClock_Config();
    , o( D7 h1 K$ \6 B# j
  11.       MX_GPIO_Init();
    " c2 z. ]' Y# I+ L
  12.       MX_USART2_UART_Init();
    7 v5 n/ W; ?1 @9 E
  13.       printf("\n\rWake Up From RTC  \n\r");
    : J5 y0 S  e$ @
  14.           }
    , p6 r6 |; c4 _% e* K$ H
  15. ........9 k+ ^" \. {6 d( C+ T0 W
复制代码
至此,RTC 唤醒的功能就完整了
" a& E: [, F4 r- X7 [
STOP2 状态定时5秒唤醒动图:  e; J1 J/ p) P6 @, y* b8 H
STOP2 停止五秒唤醒_20170706230845.gif 9 _: I  ~6 C( y0 @- U9 j/ O% V1 v

$ B- o, c" i9 p8 e
  {& ?1 n: o9 Q( O6 o  \
7 Q  C* T4 A7 y' J& X; ?3 E" O. Z) j7 h( n  G$ L! Z
代码参考前一章节的内容作了适当调整,见附件Main.rar
4 s+ \3 G" ?' j  g
6 v5 J! [3 Y/ t5 ^4 i! 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
哇哦,楼主又有更新了,过来支持下/ @- k6 ^9 u0 z  t' Q
1 R0 |' ~5 Y5 J
帮楼主把代码部分格式改了下,下次也可以这样操作哦
( X+ b1 n+ s" R. d; P0 ^4 E 1212.png 6 _9 }. a0 g# c8 j" J% a! l4 u
wolfgang 回答时间:2017-7-6 10:25:01
zero99 发表于 2017-7-6 09:598 Q7 d1 j( @1 y9 w
哇哦,楼主又有更新了,过来支持下
3 y0 m. a* J5 W% r
5 I3 M% `  x9 \5 b' M6 Q帮楼主把代码部分格式改了下,下次也可以这样操作哦

$ [* o4 T/ C' S: o2 F好,谢谢~~
epochal 回答时间:2017-7-6 11:15:59
谢谢分享!
wolfgang 回答时间:2017-7-6 22:13:54
唤醒的代码说明补全了
世事莫太贪-255746 回答时间:2020-1-9 10:08:31
谢谢分享

所属标签

相似分享

官网相关资源

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