一只香榴莲 发表于 2023-10-30 22:36

【测评STM32L452Nucleo-64】低功耗的使用和代码撰写

<div class='showpostmsg'><p>Stm32低功耗模式分为四种分别是运行模式、睡眠模式、停止模式、待机模式</p>

<p >其中运行模式就是我们平时正常工作时所使用的模式,就不做过多赘述。</p>

<p >睡眠模式进入方式使内核寄存器SLEEPDEEP=0,调用WFI(中断方式)或者WFE(事件方式)进入睡眠模式,SLEEPONEXIT=0,立即睡眠,SLEEPONEXIT=1,退出时睡眠,唤醒时无延迟,没有关闭外设,唤醒后执行中断模式,RAM并没有断电。</p>

<p >&nbsp;</p>

<p >停止模式进入方式是内核寄存器SLEEPDEEP=1,PWR_CR寄存器PDDS=0,调用WFI或者WFE进入停止模式,其中;</p>

<p >PWR_CR寄存器LPDS=0,调压器正常</p>

<p >PWR_CR寄存器LPDS=1,低功耗模式</p>

<p >PWR_CR寄存器FPDS=0,Flash正常</p>

<p >PWR_CR寄存器FPDS=0,Flash掉电</p>

<p >睡眠时会关闭内核时钟、关闭外设时钟、但是保留运行数据,再次唤醒时会有延时首先需要唤醒外部时钟,flash恢复时间,唤醒执行完中断函数后会继续进行睡眠模式。</p>

<p >&nbsp;</p>

<p >待机模式进入方式是内核寄存器SLEEPDEEP=1,PWR_CR寄存器PDDS=1,PWR_CR寄存器WUF=0,调用WFI或者WFE进入停止模式;使用WKUP上升沿、RTC闹钟、看门狗唤醒,</p>

<p>睡眠是会关闭内核、关闭外设、内存数据丢失,开启时相当于重新开机执行while函数。</p>

<p>在HAL函数库电源函数部分中中对各函数已经进行了定义</p>

<div style="text-align: center;"></div>

<p>其中睡眠模式函数如下:</p>

<pre>
<code>/**
* @brief Enter Sleep or Low-power Sleep mode.
* @noteIn Sleep/Low-power Sleep mode, all I/O pins keep the same state as in Run mode.
* @param Regulator: Specifies the regulator state in Sleep/Low-power Sleep mode.
*          This parameter can be one of the following values:
*            @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode)
*            @arg @ref PWR_LOWPOWERREGULATOR_ON Low-power Sleep mode (regulator in low-power mode)
* @noteLow-power Sleep mode is entered from Low-power Run mode. Therefore, if not yet
*      in Low-power Run mode before calling HAL_PWR_EnterSLEEPMode() with Regulator set
*      to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
*      Flash in power-down monde in setting the SLEEP_PD bit in FLASH_ACR register.
*      Additionally, the clock frequency must be reduced below 2 MHz.
*      Setting SLEEP_PD in FLASH_ACR then appropriately reducing the clock frequency must
*      be done before calling HAL_PWR_EnterSLEEPMode() API.
* @noteWhen exiting Low-power Sleep mode, the MCU is in Low-power Run mode. To move in
*      Run mode, the user must resort to HAL_PWREx_DisableLowPowerRunMode() API.
* @param SLEEPEntry: Specifies if Sleep mode is entered with WFI or WFE instruction.
*         This parameter can be one of the following values:
*            @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep mode with WFI instruction
*            @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep mode with WFE instruction
* @noteWhen WFI entry is used, tick interrupt have to be disabled if not desired as
*      the interrupt wake up source.
* @retval None
*/
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
{
/* Check the parameters */
assert_param(IS_PWR_REGULATOR(Regulator));
assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));

/* Set Regulator parameter */
if (Regulator == PWR_MAINREGULATOR_ON)
{
    /* If in low-power run mode at this point, exit it */
    if (HAL_IS_BIT_SET(PWR-&gt;SR2, PWR_SR2_REGLPF))
    {
      if (HAL_PWREx_DisableLowPowerRunMode() != HAL_OK)
      {
      return ;
      }
    }
    /* Regulator now in main mode. */
}
else
{
    /* If in run mode, first move to low-power run mode.
       The system clock frequency must be below 2 MHz at this point. */
    if (HAL_IS_BIT_SET(PWR-&gt;SR2, PWR_SR2_REGLPF) == RESET)
    {
      HAL_PWREx_EnableLowPowerRunMode();
    }
}

/* Clear SLEEPDEEP bit of Cortex System Control Register */
CLEAR_BIT(SCB-&gt;SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

/* Select SLEEP mode entry -------------------------------------------------*/
if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
{
    /* Request Wait For Interrupt */
    __WFI();
}
else
{
    /* Request Wait For Event */
    __SEV();
    __WFE();
    __WFE();
}

}
</code></pre>

<p>函数库对于各变量的定义都有严格的说明</p>

<p>在main函数中调用如下</p>

<pre>
<code>//睡眠模式
      printf("aaaa\r\n");//a可以打印完全
                HAL_SuspendTick ();
                HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);//进入睡眠模式
                printf ("aaa\r\n");//b也可以被打印</code></pre>

<p>停止模式定义函数如下:</p>

<pre>
<code>/**
* @brief Enter Stop mode
* @noteThis API is named HAL_PWR_EnterSTOPMode to ensure compatibility with legacy code running
*      on devices where only "Stop mode" is mentioned with main or low power regulator ON.
* @noteIn Stop mode, all I/O pins keep the same state as in Run mode.
* @noteAll clocks in the VCORE domain are stopped; the PLL, the MSI,
*      the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
*      (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
*      after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
*      only to the peripheral requesting it.
*      SRAM1, SRAM2 and register contents are preserved.
*      The BOR is available.
*      The voltage regulator can be configured either in normal (Stop 0) or low-power mode (Stop 1).
* @noteWhen exiting Stop 0 or Stop 1 mode by issuing an interrupt or a wakeup event,
*         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
*         is set; the MSI oscillator is selected if STOPWUCK is cleared.
* @noteWhen the voltage regulator operates in low power mode (Stop 1), an additional
*         startup delay is incurred when waking up.
*         By keeping the internal regulator ON during Stop mode (Stop 0), the consumption
*         is higher although the startup time is reduced.
* @param Regulator: Specifies the regulator state in Stop mode.
*          This parameter can be one of the following values:
*            @arg @ref PWR_MAINREGULATOR_ONStop 0 mode (main regulator ON)
*            @arg @ref PWR_LOWPOWERREGULATOR_ONStop 1 mode (low power regulator ON)
* @param STOPEntry: Specifies Stop 0 or Stop 1 mode is entered with WFI or WFE instruction.
*          This parameter can be one of the following values:
*            @arg @ref PWR_STOPENTRY_WFIEnter Stop 0 or Stop 1 mode with WFI instruction.
*            @arg @ref PWR_STOPENTRY_WFEEnter Stop 0 or Stop 1 mode with WFE instruction.
* @retval None
*/
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
{
/* Check the parameters */
assert_param(IS_PWR_REGULATOR(Regulator));

if(Regulator == PWR_LOWPOWERREGULATOR_ON)
{
    HAL_PWREx_EnterSTOP1Mode(STOPEntry);
}
else
{
    HAL_PWREx_EnterSTOP0Mode(STOPEntry);
}
}
</code></pre>

<p>在主函数中调用如下;</p>

<pre>
<code>//停止模式对于唤醒时外部时钟设置
__HAL_RCC_HSE_CONFIG (RCC_HSE_ON );
        __HAL_RCC_PLL_ENABLE ();
        __HAL_RCC_SYSCLK_CONFIG (RCC_SYSCLKSOURCE_PLLCLK );</code></pre>

<pre>
<code>printf("aaaa\r\n");//不一定能打印完全可以增加延迟
                HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI );
                printf ("aaa\r\n");//恢复时打印完全</code></pre>

<p>其中分为两个部分写在while外是在唤醒停止模式时外部时钟的定义,在while里是进入和唤醒停止模式</p>

<p>待机模式函数如下:</p>

<pre>
<code>/**
* @brief Enter Standby mode.
* @noteIn Standby mode, the PLL, the HSI, the MSI and the HSE oscillators are switched
*      off. The voltage regulator is disabled, except when SRAM2 content is preserved
*      in which case the regulator is in low-power mode.
*      SRAM1 and register contents are lost except for registers in the Backup domain and
*      Standby circuitry. SRAM2 content can be preserved if the bit RRS is set in PWR_CR3 register.
*      To enable this feature, the user can resort to HAL_PWREx_EnableSRAM2ContentRetention() API
*      to set RRS bit.
*      The BOR is available.
* @noteThe I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
*      HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() respectively enable Pull Up and
*      Pull Down state, HAL_PWREx_DisableGPIOPullUp() and HAL_PWREx_DisableGPIOPullDown() disable the
*      same.
*      These states are effective in Standby mode only if APC bit is set through
*      HAL_PWREx_EnablePullUpPullDownConfig() API.
* @retval None
*/
void HAL_PWR_EnterSTANDBYMode(void)
{
/* Set Stand-by mode */
MODIFY_REG(PWR-&gt;CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STANDBY);

/* Set SLEEPDEEP bit of Cortex System Control Register */
SET_BIT(SCB-&gt;SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM)
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
</code></pre>

<p>在while中使用待机模式代码如下</p>

<pre>
<code>printf("aaaa\r\n");
                HAL_PWR_EnableWakeUpPin (PWR_WAKEUP_PIN1_LOW);
                __HAL_PWR_CLEAR_FLAG (PWR_FLAG_WU );
                HAL_PWR_EnterSTANDBYMode();
                printf("aaaa\r\n");//唤醒不执行</code></pre>

<p>&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

lugl4313820 发表于 2023-11-2 10:23

期待楼主的功耗测试结果,如果能做到纳安级别的待机,那就强了。
页: [1]
查看完整版本: 【测评STM32L452Nucleo-64】低功耗的使用和代码撰写