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

查看: 3015|回复: 7

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

[复制链接]

74

主题

1368

回帖

194

蝴蝶豆

版主

最后登录
2020-5-12
发表于 2017-7-5 22:53:54 | 显示全部楼层 |阅读模式

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

——进入Stop2模式,延时5秒后唤醒



一、实验开始之前
    上一章节次实验实现的是进入低功耗后测得的电流值,但在要在实际应用中,只能进入低功耗是不够的。需要能进入低功耗后根据实际需要和应用场景实现频率、电源的恢复,能恢复到进入低功耗前的处理能力。本章就针对进入Stop2模式 后的经过RTC定时五秒后恢复进行数据测量。

二、实验过程1、实验前探索
1.1 RTC时钟源选择
  在正式实验前,将功能树上的是RTC功能打开,并在时钟树上查看RTC时钟源频率。


01.jpg


02.jpg


   从时钟数可以看到RTC时钟频率使用的是LSI RC的32KHz的频率。当然也能选择LSE或者HSE的RTC分频后的时钟作为RTC时钟源,进入除Shutdown模式外的低功耗(因实验中板卡为Nucleo L476RG 缺少LSE,无法对Shutdown模式进行唤醒,需要另外焊接LSE 的元器件后方可进行实验),将时钟源统一为LSI 的RC,具体的产品环境根据实际需要选择时钟源。
1.2 时钟源相关设置
03.jpg

  设置唤醒时钟为 32K的16分频,频率为2K,唤醒定为5秒后,这里设置5*2K=10K次。

设置唤醒中断使能。
04.jpg
1.3 LSI时钟功耗
将LSI、RTC始终设置后,因增加了设备,会增加进入功耗时的功耗值,分别测试打开LSI、RTC后的功耗值如下:
RUN:              15mA;(外设功能活动)
SHUTDOWN:      0.09uA;(外设功能停止)
STANDBY:       0.68uA;(外设功能停止)
STOP2:         2.13uA;(外设功能停止)
LPSLEEP2MHz:     87uA(外设功能活动);

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){
  2.          RCC_OscInitTypeDef    RCC_OscInitStruct;
  3.          RCC_PeriphCLKInitTypeDef    PeriphClkInit;
  4.          RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSI;
  5.          RCC_OscInitStruct.LSIState    = RCC_LSI_ON;
  6.      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  7.      {
  8.        _Error_Handler(__FILE__, __LINE__);
  9.      }
复制代码
  1. PeriphClkInit.PeriphClockSelection    = RCC_PERIPHCLK_RTC;
  2.          PeriphClkInit.RTCClockSelection    = RCC_RTCCLKSOURCE_LSI;
  3.          if    (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  4.      {
  5.        _Error_Handler(__FILE__, __LINE__);
  6.      }

  7.      /**Configure the main internal regulator output voltage
  8.    
  9.      */
  10.      if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) !=    HAL_OK)
  11.      {
  12.        _Error_Handler(__FILE__, __LINE__);
  13.      }
  14. }
复制代码


RTC初始化,过去早的初始化RTC,增加正常工作时的功耗,若需要RTC在项目全生命周期工作的情况除外。
  1. tatic void MX_RTC_Init(void)
  2. {
  3.      RTC_TimeTypeDef sTime;
  4.      RTC_DateTypeDef sDate;

  5.      /**Initialize RTC Only
  6.       */
  7.      hrtc.Instance = RTC;
  8.      hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  9.      hrtc.Init.AsynchPrediv = 127;
  10.      hrtc.Init.SynchPrediv = 255;
  11.      hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  12.      hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  13.      hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  14.      hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  15.      if (HAL_RTC_Init(&hrtc) != HAL_OK)
  16.      {
  17.        _Error_Handler(__FILE__, __LINE__);
  18.      }
复制代码
  1. /**Initialize RTC and set the Time and Date
  2.    
  3.       */
  4.      if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
  5.      sTime.Hours = 0x0;
  6.      sTime.Minutes = 0x0;
  7.      sTime.Seconds = 0x0;
  8.      sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  9.      sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  10.      if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) !=    HAL_OK)
  11.      {
  12.        _Error_Handler(__FILE__, __LINE__);
  13.      }

  14.      sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  15.      sDate.Month = RTC_MONTH_JANUARY;
  16.      sDate.Date = 0x1;
  17.      sDate.Year = 0x0;

  18.      if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) !=    HAL_OK)
  19.      {
  20.        _Error_Handler(__FILE__, __LINE__);
  21.      }

  22.        HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
  23.      }
  24. }
复制代码


设置RTC从STOP模式唤醒后的系统时钟以及事件唤醒中断:
  1. HAL_RCCEx_WakeUpStopCLKConfig(RCC_STOP_WAKEUPCLOCK_HSI);
  2. HAL_RTCEx_SetWakeUpTimer_IT(&hrtc,    20480, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
复制代码

随后就能进入STOP2模式了,直接调用Test_Stop2()。

在进入STOP2模式后, 经历RTC计数到达唤醒设定的延时时间,及触发RTC_WKUP中断,
在HAL生成的中断函数里调用了唤醒中断函数, HAL_RTCEx_WakeUpTimerIRQHandler(xxxx),
其中的HAL_RTCEx_WakeUpTimerEventCallback()回调函数,是需要根据开发者自己定义的,


  1. void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
  2.         WakeUpState=1;
  3. }
复制代码
考虑到唤醒中断优先级,这里只标记唤醒状态,具体唤醒后的操作交由主循环中的内容只执行:
  1. ........
  2.      if (WakeUpState){
  3.                   WakeUpState=0;
  4.           //禁用RTC 定时器WakeUP,避免再次出发唤醒
  5.                   HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
  6.                   //初始化变量及引脚功能
  7.                   EXTI_State = DISABLE;
  8.                
  9.       //HAL_Init();
  10.       SystemClock_Config();
  11.       MX_GPIO_Init();
  12.       MX_USART2_UART_Init();
  13.       printf("\n\rWake Up From RTC  \n\r");
  14.           }
  15. ........
复制代码
至此,RTC 唤醒的功能就完整了

STOP2 状态定时5秒唤醒动图:
STOP2 停止五秒唤醒_20170706230845.gif




代码参考前一章节的内容作了适当调整,见附件Main.rar

main.rar (6.04 KB, 下载次数: 115)
回复

使用道具 举报

74

主题

1368

回帖

194

蝴蝶豆

版主

最后登录
2020-5-12
 楼主| 发表于 2017-7-5 23:09:30 | 显示全部楼层
最近工作比较忙,再加上电脑重装系统,这篇文章等得有些久了。。。。
回复 支持 反对

使用道具 举报

47

主题

3404

回帖

30

蝴蝶豆

版主

最后登录
2020-12-7
发表于 2017-7-6 08:43:26 | 显示全部楼层
多谢分享。。
回复 支持 反对

使用道具 举报

1182

主题

3785

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-3-17
发表于 2017-7-6 09:59:27 | 显示全部楼层
哇哦,楼主又有更新了,过来支持下

帮楼主把代码部分格式改了下,下次也可以这样操作哦
1212.png
回复 支持 反对

使用道具 举报

74

主题

1368

回帖

194

蝴蝶豆

版主

最后登录
2020-5-12
 楼主| 发表于 2017-7-6 10:25:01 | 显示全部楼层
zero99 发表于 2017-7-6 09:59
哇哦,楼主又有更新了,过来支持下

帮楼主把代码部分格式改了下,下次也可以这样操作哦

好,谢谢~~
回复 支持 反对

使用道具 举报

0

主题

2175

回帖

3

蝴蝶豆

论坛元老

最后登录
2020-12-9
发表于 2017-7-6 11:15:59 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

74

主题

1368

回帖

194

蝴蝶豆

版主

最后登录
2020-5-12
 楼主| 发表于 2017-7-6 22:13:54 | 显示全部楼层
唤醒的代码说明补全了
回复 支持 反对

使用道具 举报

0

主题

2

回帖

0

蝴蝶豆

新手上路

最后登录
2020-1-9
发表于 2020-1-9 10:08:31 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

请先关注话题后回复
关于 意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
13245底部标题123相同标题
12底部标题123相同标题
33333底部标题123相同序号
3435底部标题-无链接
关注我们
st-img 微信公众号
st-img 手机版