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:

有低功耗的項目中,看門狗監測目前沒有找到好的方式,使用看門狗監測程序但它會破壞低功耗,查詢很多資料論壇后,還是選擇了放棄看門狗,看門狗被開啟,就不能再軟件關閉了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM