打印
[其他ST产品]

STM32MX电源管理低功耗模式

[复制链接]
399|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言:
ST官方例程:(直接移植直接用,接口是现成的)

在你STM32Cube固件库安装路径下.

.\..\STM32Cube\Repository\STM32Cube_FW_F4_V1.23.0\Projects\STM32F429I-Discovery\Examples\PWR\PWR_CurrentConsumption

下面手册文字截图来源于《STM32F4xx中文参考手册.PDF》的第5 电源控制器(PWR)的5.3 低功耗模式

STM32电源三种低功耗模式介绍

节省功耗(最省电)效果:待机  > 停止 > 睡眠。


手册反复提到了事件和中断这两个词。


使用特权

评论回复
沙发
感觉很反感mva|  楼主 | 2022-10-19 15:10 | 只看该作者
1. 事件(WFI)和中断(WFE)的区别:
事件:包括中断事件和非中断事件。

非中断事件:如GPIO电平变化,外设使能,初始化等不发生中断的事件。

中断事件:例如按键,按下按键会引起GPIO电平的变化(非中断事件)。若把按键配置为外部中断,即把非中断事件变成中断事件。中断是发生中断事件后执行对应的xxx_IRQHandler()中断服务函数。

详细原理框图可以看STM32F4XX英文参考手册的Figure 41. External interrupt/event controller block diagram

使用特权

评论回复
板凳
感觉很反感mva|  楼主 | 2022-10-19 15:11 | 只看该作者
2. 睡眠模式
2.1 手册




注意:睡眠模式下,无论设置事件(WFI)和中断(WFE),系统时钟SysTick_Handler()都能将其唤醒。

使用特权

评论回复
地板
感觉很反感mva|  楼主 | 2022-10-19 15:18 | 只看该作者
2.2 软件步骤(粗体是必做步骤):
1、进入睡眠前可以降低或者关闭外设的时钟速度达到更好的效果(唤醒后要恢复外设时钟)。

2、失能系统时钟SysTick_Handler()中断。

3、设置唤醒方式,进入睡眠模式(CPU时钟关闭,内核停止,对其他时钟和ADC时钟无影响,不改变GPIO管脚状态)。

4、唤醒方式:任意中断唤醒或者事件(具体看你设置的唤醒方式)

5、唤醒延时:无

6、唤醒之后:使能系统时钟SysTick_Handler()中断(唤醒后要恢复外设时钟)。

7、程序继续运行。

使用特权

评论回复
5
感觉很反感mva|  楼主 | 2022-10-19 15:20 | 只看该作者
代码:
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  This function configures the system to enter Sleep mode for
  *         current consumption measurement purpose.
  *         Sleep Mode
  *         ==========  
  *            - System Running at PLL
  *            - Flash 5 wait state
  *            - Instruction and Data caches ON
  *            - Prefetch ON   
  *            - Code running from Internal FLASH
  *            - All peripherals disabled.
  *            - Wakeup using EXTI Line (USER Button)
  * @param  None
  * @retval None
  */
void SleepMode_Measure(void)
{
  //挂起(暂停)系统时钟中断
  HAL_SuspendTick();
  
  /* 进入睡眠模式, 任意中断唤醒 */
  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
  
  /* 恢复系统时钟中断 */
  HAL_ResumeTick();
  
  /* Add a delay of 200ms after exit from Sleep mode */
  HAL_Delay(200);
}

使用特权

评论回复
6
感觉很反感mva|  楼主 | 2022-10-19 16:53 | 只看该作者
停止模式
3.1 手册

使用特权

评论回复
7
感觉很反感mva|  楼主 | 2022-10-19 17:06 | 只看该作者

使用特权

评论回复
8
感觉很反感mva|  楼主 | 2022-10-19 17:33 | 只看该作者
软件步骤(粗体是必做步骤):
1、进入睡眠前可以降低或者关闭外设的时钟速度达到更好的效果(唤醒后要恢复外设时钟)。

2、芯片内部FLASH掉电。

3、设置唤醒方式:_WFI 或者 _WFE,(RTC闹钟中断也可以唤醒,后面说)

4、关闭电压调节器(电压调节器是动态调节芯片内部电压,关闭后更加节省功耗,但是唤醒时间加长)

5、进入停止模式:所有的1.2V时钟都关闭(HSI和HSE的振荡器关闭,不改变GPIO管脚状态)。

6、唤醒方式:任意外部中断 或者 RTC闹钟

7、唤醒延时:有,(关闭电压调节器唤醒时间更长)。

8、唤醒之后:重新初始化时钟。

9、程序继续运行。

使用特权

评论回复
9
感觉很反感mva|  楼主 | 2022-10-19 17:34 | 只看该作者
代码:
下面有两个停止模式函数StopMode_Measure()和StopUnderDriveMode_Measure();

前者是没有关闭电压调节器的,后者是关闭了电压调节器的,但是唤醒时间加长。

两个函数都RTC闹钟定时了20s唤醒。若不喜欢用RTC删除即可。

使用特权

评论回复
10
感觉很反感mva|  楼主 | 2022-10-19 17:34 | 只看该作者
extern void SystemClock_Config(void);   //外部链接用户初始化时钟

/**
  * @brief  This function configures the system to enter Stop mode with RTC
  *         clocked by LSE or LSI  for current consumption measurement purpose.
  *         STOP Mode with RTC clocked by LSE/LSI
  *         =====================================   
  *           - RTC Clocked by LSE or LSI
  *           - Regulator in LP mode
  *           - HSI, HSE OFF and LSI OFF if not used as RTC Clock source
  *           - No IWDG
  *           - FLASH in deep power down mode
  *           - Automatic Wakeup using RTC clocked by LSE/LSI (~20s)
  * @param  None
  * @retval None
  *
  * @NOTE      
  *             此函数  没有关闭电压调节器  
  *
  */
void StopMode_Measure(void)
{
  RTCHandle.Instance = RTC;

  RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

  if(HAL_RTC_Init(&RTCHandle) != HAL_OK)
  {
    Error_Handler();
  }

  /*## 配置RTC唤醒 20s唤醒 ###########################################*/
  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0xA017, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

  /* flash进入掉电 */
  HAL_PWREx_EnableFlashPowerDown();

  /*进入停止模式, 外部中断唤醒或者RTC闹钟唤醒 */
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

   //重新初始化时钟
  SystemClock_Config();
  
  /* Disable Wake-up timer */
  if(HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
}

/**
  * @brief  This function configures the system to enter in Under-Drive stop mode with RTC
  *         clocked by LSE or LSI  for current consumption measurement purpose.
  *         STOP Mode with RTC clocked by LSE/LSI
  *         =====================================   
  *           - RTC Clocked by LSE or LSI
  *           - Regulator in LP mode
  *           - Under drive feature enabled
  *           - HSI, HSE OFF and LSI OFF if not used as RTC Clock source
  *           - No IWDG
  *           - FLASH in deep power down mode
  *           - Automatic Wakeup using RTC clocked by LSE/LSI (~20s)
  * @param  None
  * @retval None
  *
  * @note      
  *             此函数  关闭电压调节器  ,唤醒需要的时间更长,但是功耗理论更小
  *
  */
void StopUnderDriveMode_Measure(void)
{
  RTCHandle.Instance = RTC;

  /* Configure RTC prescaler and RTC data registers as follow:
      - Hour Format = Format 24
      - Asynch Prediv = Value according to source clock
      - Synch Prediv = Value according to source clock
      - OutPut = Output Disable
      - OutPutPolarity = High Polarity
      - OutPutType = Open Drain */
  RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

  if(HAL_RTC_Init(&RTCHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /*## Configure the Wake up timer ###########################################*/
  /*  RTC Wakeup Interrupt Generation:
      Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI))
      Wakeup Time = Wakeup Time Base * WakeUpCounter
                  = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI)) * WakeUpCounter
      ==> WakeUpCounter = Wakeup Time / Wakeup Time Base
      To configure the wake up timer to 20s the WakeUpCounter is set to 0xA017:
        RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16
        Wakeup Time Base = 16 /(~32.768KHz) = ~0,488 ms
        Wakeup Time = ~20s = 0,488ms  * WakeUpCounter
        ==> WakeUpCounter = ~20s/0,488ms = 40983 = 0xA017 */
  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0xA017, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

  /* FLASH Deep Power Down Mode enabled */
  HAL_PWREx_EnableFlashPowerDown();

  /* Enter under-drive Stop Mode */
  HAL_PWREx_EnterUnderDriveSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

  /* Configures system clock after wake-up from STOP: enable HSE, PLL and select
     PLL as system clock source (HSE and PLL are disabled in STOP mode) */
//  SYSCLKConfig_STOP();
  SystemClock_Config();
  
  /* Disable Wake-up timer */
  if(HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
}

使用特权

评论回复
11
感觉很反感mva|  楼主 | 2022-10-19 17:42 | 只看该作者
待机模式
4.1 手册

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

50

帖子

0

粉丝