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

查看: 3019|回复: 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版