[STM32U0]【STM32U083测评】一箭六雕测试低功耗模式的进入与唤醒

STM32U083支持如下这几种低功耗模式:sleep, low power run, low power sleep, stop0, stop1, stop2, standby, shutdown。笔者对前面六种低功耗模式比较感兴趣,所以想尝试下这些低功耗模式的进 入与唤醒。STM32Cube_FW_U0_V1.0.0中关于低功耗模式有无数个样例程序代码,那么能否只用一个程序只跑一次来测试这六种低功耗模式呢?笔者思考一番后实现了这样的代码,这就是标题中所谓一箭六雕。

低功耗模式个人解读

说明:这是阅读stm32手册后个人的猜测,可能不太准确。

sleep
以笔者的理解,sleep其实就是处理器没事做的时候在SLEEPDEEP==0的情形下执行WFI指令,cpu本身会 进入clock gating状态,手册里说CPU is stopped,其实可以更精确些“CPU clock is stopped”。退出sleep很简单,任何中断都或事件都可以退出sleep模式

low power run
手册说得比较多,笔者个人感觉一句话说清楚的,不就是DVFS嘛,降频降压。进入这种模式,cpu仍然 处于运行状态。退出low power run模式也简单,升压升频。

low power sleep
这种模式就是DVFS降频降压后,cpu无事做的时候在SLEEPDEEP==0的情形下执行WFI指令,cpu本身会进 入clock gating状态,因为电压和频率相比sleep模式都低了所以这个模式的功耗相比sleep模式会降低。

stop0
这应该是cpu处于power gating状态,但外设啥的只clock gating,regulator应该没动。进入stop0模 式的方法就是设置SLEEPDEEP=1且PWR_CR1寄存器的LPMS字段='000',执行WFI指令即可。EXTI中断线有 中断即会退出stop0模式

stop1
相比stop0,把main regulator关了。进入方式和stop0差不多,区别是设置PWR_CR1寄存器的LPMS字段='001'

stop2
在stop1基础上再进一步,把大部分的vcore域的设备都给power gating了。进入方式和stop0差不多, 区别是设置PWR_CR1寄存器的LPMS字段=‘002’

程序框架

时钟源只用MSI,启动后慢闪LED 5s, 进入每一个模式前块闪LED 5s,然后熄灭进入对应low power模式,通过USER按键中断唤醒。六个模式都测完后,LED慢闪10s以提示一轮完毕,然后再次循环。用伪码表示就是:

复制

for (;;) {

    toggle_speed = LED_TOGGLE_FAST;

    try_sleep();

    try_lprun();

    try_lpsleep();

    try_stop0();

    try_stop1();

    try_stop2();

    toggle_speed = LED_TOGGLE_SLOW;

    HAL_Delay(10000);

  }


实现try_sleep()函数如下:

复制

static void try_sleep(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Turn off LED4 */

  BSP_LED_Off(LED4);



  /* Suspend Tick increment */

  HAL_SuspendTick();



  /* Enter the CPU to SLEEP mode */

  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI) ;



  /* Resume Tick increment */

  HAL_ResumeTick();

}


实现try_lprun()函数如下:

复制

static void try_lprun(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Reduce the System clock */

  SystemClock_Decrease();



  /* Set regulator voltage to scale 2 */

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);



  /* De-init LED4 */

  BSP_LED_DeInit(LED4);



  /* Enter LP RUN Mode */

  HAL_PWREx_EnableLowPowerRunMode();



  /* Wait until User push-button pressed */

  while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET)

  {

  }



  /* Wait until User push-button released */

  while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_SET)

  {

  }



  /* Disable low power run mode and reset the clock to initialization configuration */

  HAL_PWREx_DisableLowPowerRunMode();



  /* Set regulator voltage to scale 1 */

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);



  /* Re-init LED4 to toggle during Run mode */

  BSP_LED_Init(LED4);



  /* Configure the system clock for the RUN mode */

  SystemClock_Config();

}


实现try_lpsleep()函数如下:

复制

static void try_lpsleep(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Reduce the System clock */

  SystemClock_Decrease();



  /* Set regulator voltage to scale 2 */

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);



  /* Enter LP RUN Mode */

  HAL_PWREx_EnableLowPowerRunMode();



  /* Turn off LED4 */

  BSP_LED_Off(LED4);



  /* Suspend Tick increment */

  HAL_SuspendTick();



  /* Enter the CPU to Low Power SLEEP mode */

  HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI) ;



  /* Resume Tick increment */

  HAL_ResumeTick();



  /* Disable low power run mode and reset the clock to initialization configuration */

  HAL_PWREx_DisableLowPowerRunMode();



  /* Set regulator voltage to scale 1 */

  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);



  /* Configure the system clock for the RUN mode */

  SystemClock_Config();

}


实现try_stop0()函数如下:

复制

static void try_stop0(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Turn off LED4 */

  BSP_LED_Off(LED4);



  /* Suspend Tick increment to prevent wakeup by Systick interrupt.         */

  /* Otherwise the Systick interrupt will wake up the device within 1ms     */

  /* (HAL time base).                                                       */

  HAL_SuspendTick();



  HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);

  /* ... STOP 0 mode ... */



  /* Re-configure the system clock to 48 MHz based on MSI */

  SystemClock_Config();

}




实现try_stop1()函数如下:

复制


static void try_stop1(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Turn off LED4 */

  BSP_LED_Off(LED4);



  /* Suspend Tick increment to prevent wakeup by Systick interrupt.         */

  /* Otherwise the Systick interrupt will wake up the device within 1ms     */

  /* (HAL time base).                                                       */

  HAL_SuspendTick();



  HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);

  /* ... STOP 1 mode ... */



  /* Re-configure the system clock to 48 MHz based on MSI */

  SystemClock_Config();

}


实现try_stop2()函数如下:

复制


static void try_stop1(void)

{

  /* Insert 5 second delay */

  HAL_Delay(5000);



  /* Turn off LED4 */

  BSP_LED_Off(LED4);



  /* Suspend Tick increment to prevent wakeup by Systick interrupt.         */

  /* Otherwise the Systick interrupt will wake up the device within 1ms     */

  /* (HAL time base).                                                       */

  HAL_SuspendTick();



  HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);

  /* ... STOP 1 mode ... */



  /* Re-configure the system clock to 48 MHz based on MSI */

  SystemClock_Config();

}


运行视频在https://www.bilibili.com/video/BV1Nb421B7zV/?vd_source=e03ac0ea40b8a1877cedbbaee5737b10

由此可看到sleep、low power run、low power sleep、stop0、stop1和stop2模式进入与退出均正常,但由于笔者万用表电流档烧了,所以不能测出对应模式的功耗,不然视频做得更好。
---------------------
作者:xhackerustc
链接:https://bbs.21ic.com/icview-3379734-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值