zoukankan      html  css  js  c++  java
  • STM32——项目需求之低功耗的停机模式

    在说低功耗之前,先要明白一个东西,那就是stm32中的事件和中断。

    事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断。在STM32中,中断与事件不是等价的,一个中断肯定对应一个事件,但一个事件不一定对应一个中断。

    当外部有信号输入时,如果通过了事件屏蔽寄存器,那么事件信号就进入脉冲触发器,引发一个脉冲信号,直接传递给相应的外设,用于触发,这就是一个纯硬件的过程,理解DMA的应该知道,这个方式不需要CPU参与,但是这也有它的缺点,如功能比较单一,仅能提供信号,不能提供信息,也就是只能产生指定功能的事件。如果通过中断屏蔽寄存器,就被直接送到CPU中,产生中断,如进入上面的入口函数开始处理。从这就可看出,事件是单纯硬件触发执行的过程,与CPU本身设计支持有关,而中断中则可以软件实现各种功能,而低功耗模式的事件唤醒就是stm32支持的事件之一。

    进入停止模式之后,任何外部中断都可以唤醒低功耗,但是需要重新配置时钟,不然系统将以默认时钟(没有经过倍频)运行。

    选择事件唤醒低功耗之停止模式,可以更加快速,不需要中断服务函数,自然也不需要配置NVIC的相关寄存器。

    进入低功耗库函数:

    PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFE);

    /**
      * @brief  Enters STOP mode.
      * @param  PWR_Regulator: specifies the regulator state in STOP mode.
      *   This parameter can be one of the following values:
      *     @arg PWR_Regulator_ON: STOP mode with regulator ON
      *     @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode
      * @param  PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.
      *   This parameter can be one of the following values:
      *     @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
      *     @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
      * @retval None
      */
    void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
    {
      uint32_t tmpreg = 0;
      /* Check the parameters */
      assert_param(IS_PWR_REGULATOR(PWR_Regulator));
      assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
      
      /* Select the regulator state in STOP mode ---------------------------------*/
      tmpreg = PWR->CR;
      /* Clear PDDS and LPDS bits */
      tmpreg &= CR_DS_MASK;
      /* Set LPDS bit according to PWR_Regulator value */
      tmpreg |= PWR_Regulator;
      /* Store the new value */
      PWR->CR = tmpreg;
      /* Set SLEEPDEEP bit of Cortex System Control Register */
      SCB->SCR |= SCB_SCR_SLEEPDEEP;
      
      /* Select STOP mode entry --------------------------------------------------*/
      if(PWR_STOPEntry == PWR_STOPEntry_WFI)
      {   
        /* Request Wait For Interrupt */
        __WFI();
      }
      else
      {
        /* Request Wait For Event */
        __WFE();
      }
      
      /* Reset SLEEPDEEP bit of Cortex System Control Register */
      SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);  
    }

    可以选择事件和中断唤醒两种方式,选择哪种方式是根据库函数的第二个参数决定的,这是一个宏:

    进入低功耗之后,需要事件或者中断去唤醒,这里用RTC闹钟事件选择唤醒mcu。

    RTC_SetAlarm( RTC_GetCounter()+600*N);
    RTC_ITConfig(RTC_IT_ALR, ENABLE);
    RTC_WaitForLastTask();

    上面三句话需要放在进入低功耗的函数前,这样当RTC闹钟时间到了之后,在没有其他事件或者中断唤醒的前提下,闹钟会唤醒进入停机模式的mcu。每次操作了RTC,需要等待RTC操作完成,这些在ST库函数中都给我们做好了。

    另外需要注意的是,停机模式下,mcu唤醒之后,时钟和频率是没有经过倍频的,在F1上,低功耗唤醒之后,是8M频率运行,而正常运行是72M。所以,在唤醒停机模式之后,需要重新配置时钟。

    ST很贴心,直接调用库函数:

    SystemInit();

    就可以了。那么整体流程就是:

                RTC_SetAlarm( RTC_GetCounter()+600*N);
                RTC_ITConfig(RTC_IT_ALR, ENABLE);
                RTC_WaitForLastTask();
                PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFE);
                SystemInit();
                RTC_WaitForSynchro();

    上面的代码,裸机中推荐放在while(1)最后,带os应该在空闲任务中。

    Advance:

    有低功耗的项目中,看门狗监测目前没有找到好的方式,使用看门狗监测程序但它会破坏低功耗,查询很多资料论坛后,还是选择了放弃看门狗,看门狗被开启,就不能再软件关闭了。

  • 相关阅读:
    Windowsforms 中对文件操作
    ADO.net增删改的使用
    ADO.net数据访问
    可空类型
    FineUI 页面跳转
    ASP.NET页面之间传递值的几种方式
    C# Find() 与 FindAll()方法的使用
    在Sql中将 varchar 值 '1,2,3,4,5,6' 转换成数据类型 int
    DataSet、DataTable、DataRow、DataColumn区别及使用实例
    C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/7441756.html
Copyright © 2011-2022 走看看