STM32F0的低功耗模式


STM32的低功耗模式有三種, STOP, SLEEP, STANDBY.

其中SLEEP沒啥用, 好處是一戳就醒.

最低功耗是STANDBY模式, 據說只有2ua電流, 但是每次醒來, 就相當於重啟了, SRAM全重置, 另外一個壞處是需要指定一個PA0腳, 即WAKEUP腳的上升沿喚醒.

最好用的應該就是這個STOP模式, 寄存器跟SRAM都保存狀態, 連IO都保持, 喚醒的方法是外部中斷跟通訊, 通訊還沒測試, 外部中斷是ok了.

 

進中斷的方法很簡單:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_SLEEPEntry_WFI);

但是之前要設置要外部中斷, 比如一個按鍵:

 

     GPIO_InitTypeDef GPIO_InitStruct; 
     EXTI_InitTypeDef EXTI_InitStruct;
     NVIC_InitTypeDef NVIC_InitStruct;

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);              
              
     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; 
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_2;
     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 
     GPIO_Init(GPIOB, &GPIO_InitStruct);

     SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);

     EXTI_ClearITPendingBit(EXTI_Line12);
              
     EXTI_InitStruct.EXTI_Line = EXTI_Line12;
     EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; 
     EXTI_InitStruct.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStruct); 

     NVIC_InitStruct.NVIC_IRQChannel = EXTI4_15_IRQn;
     NVIC_InitStruct.NVIC_IRQChannelPriority = 0x01;
     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStruct);

 

為了防止醒來之后時鍾的問題:

void SYSCLKConfig_STOP(void)
{  
  /* After wake-up from STOP reconfigure the system clock */
  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);
  
  /* Wait till HSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
  {}
  
  /* Enable PLL */
  RCC_PLLCmd(ENABLE);
  
  /* Wait till PLL is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  {}
  
  /* Select PLL as system clock source */
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  
  /* Wait till PLL is used as system clock source */
  while (RCC_GetSYSCLKSource() != 0x08)
  {}
}

 結果這里發現一個問題, 我先是需要使用一個TIM來進行定時任務, 我的目標是, 如果系統空閑超過一段時間, 比如20秒, 就進入STOP模式, 結果發現在定時器的irq_hendle函數中, 無法進入低功耗, 沒轍, 在main里面增加了一個全局變量, 用TIM將這個變量置, 在main的while循環中去進入STOP模式.

 

        if(ifGotoStop){
            printf("sleepy\r\n");

            sysEnterStopMode();
            //System_Init();
            //TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
            SYSCLKConfig_STOP();
            printf("go out\r\n");
            ifGotoStop = 0;
        }

 

喚醒的按鍵中斷(增加了去抖):

void EXTI4_15_IRQHandler(void)
{ 		

    if(EXTI_GetITStatus(EXTI_Line12)!=RESET)  {
       
        while(TEST_KEY == RESET){
            timeCounter++;
        }
        if(timeCounter > 10000){
            printf("wake up! \r\n");
        }
        timeCounter = 0;
        //LED05_OFF;

    }  
	EXTI_ClearITPendingBit(EXTI_Line12); 

} 

 

剩下的就是檢查低功耗時候的電流, 以及增加串口輸入的中斷作為喚醒條件.


免責聲明!

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



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