STM32-電源控制、低功耗模式


STM32的電源控制

STM32的電源框圖

STM32的工作電壓(VDD)為2.0~3.6V。通過內置的電壓調節器提供所需的1.8V電源。 當主電源VDD掉電后,通過VBAT腳為實時時鍾(RTC)和備份寄存器提供電源。

下面是STM32的電源框圖:

注意:框圖中的VDDA和VSSA必須分別聯到VDD和VSS。

獨立的A/D轉換器供電和參考電壓

為了提高轉換的精確度,ADC使用一個獨立的電源供電,過濾和屏蔽來自印刷電路板上的毛刺干擾。

  • ADC的電源引腳為VDDA;
  • 獨立的電源地VSSA。

如果有VREF-引腳(根據封裝而定),它必須連接到VSSA。同時,為了確保輸入為低壓時獲得更好精度,用戶可以連接一個獨立的外部參考電壓ADC到VREF+和VREF-腳上。在VREF+的電壓范圍為2.4V~VDDA。

電池備份區域

使用電池或其他電源連接到VBAT腳上,當VDD斷電時,可以保存備份寄存器的內容和維持RTC的功能。 

VBAT腳也為RTC、LSE振盪器和PC13至PC15供電,這保證當主要電源被切斷時RTC能繼續工作。切換到VBAT供電由復位模塊中的掉電復位功能控制。 如果應用中沒有使用外部電池,VBAT必須連接到VDD引腳上。

電壓調節器

復位后調節器總是使能的。根據應用方式它以3種不同的模式工作:

  • 運行模式:調節器以正常功耗模式提供1.8V電源(內核,內存和外設);
  • 停止模式:調節器以低功耗模式提供1.8V電源,以保存寄存器和SRAM的內容;
  • 待機模式:調節器停止供電。除了備用電路和備份域外,寄存器和SRAM的內容全部丟失。

 

STM32的低功耗模式

很多單片機有低功耗模式,STM32也不例外。在系統或者電源復位后,微控制器出於運行狀態之下,HCLK為CPU提供時鍾,內核執行代碼。當CPU不需要繼續運行時,可以利用多種低功耗模式來節省功耗,例如等待某個事件觸發。

低功耗模式分類

STM32有三種低功耗模式:

  • 睡眠模式:Cortex-M3內核停止,所有外設包括Cortex-M3核心的外設,如NVIC、系統時鍾(SysTick)等仍在運行;
  • 停止模式:所有時鍾都已停止。
  • 待機模式:1.8V內核電源關閉。

在運行模式下,可以通過下面方式降低功耗:

  • 降低系統時鍾:

在運行模式下,通過對預分頻寄存器進行編程,可以降低任意一個系統時鍾(SYSCLK、HCLK、PCLK1、PCLK2)的速度。進入睡眠模式前,也可以利用預分頻器來降低外設的時鍾;

  • 關閉APB和AHB總線上未被使用的外設時鍾:

在運行模式下,任何時候都可以通過停止為外設和內存提供時鍾(HCLK和PCLKx)來減少功耗。 為了在睡眠模式下更多地減少功耗,可在執行WFI或WFE指令前關閉所有外設的時鍾。 通過設置AHB外設時鍾使能寄存器 (RCC_AHBENR)、APB2外設時鍾使能寄存器(RCC_APB2ENR)和APB1外設時鍾使能寄存器(RCC_APB1ENR)來開關各個外設模塊的時鍾。

睡眠模式

在睡眠模式下,Cortex-M3內核停止,所有外設包括Cortex-M3核心的外設,如NVIC、系統時鍾(SysTick)等仍在運行,也就是說:所有的I/O引腳都保持它們在運行模式時的狀態。

該模式喚醒所需的時間最短,因為沒有時間損失在中斷的進入或退出上。

停止模式

停止模式是在Cortex™-M3的深睡眠模式基礎上結合了外設的時鍾控制機制,在停止模式下電壓調節器可運行在正常或低功耗模式。此時在1.8V供電區域的的所有時鍾都被停止,但1.8V供電區域仍通電,PLL、HSI和HSE RC振盪器的功能被禁止,SRAM和寄存器內容被保留下來。

在停止模式下,所有的I/O引腳都保持它們在運行模式時的狀態。

待機模式

待機模式可實現系統的最低功耗。該模式是在Cortex-M3深睡眠模式時關閉電壓調節器。整個1.8V供電區域被斷電。PLL、HSI和HSE振盪器也被斷電。SRAM和寄存器內容丟失。只有備份的寄存器和待機電路維持供電。

在待機模式下,所有的I/O引腳處於高阻態,除了以下的引腳:

  • 復位引腳(始終有效);
  • 當被設置為防侵入或校准輸出時的TAMPER引腳;
  • 被使能的喚醒引腳。

 

電源控制相關配置寄存器

電源控制寄存器(PWR_CR)

作用:掉電深度睡眠位的設置(停止模式和待機模式)。

電源控制/狀態寄存器(PWR_CSR)

作用:使能WKUP引腳用於待機模式喚醒、WUF喚醒標志位。

 

電源控制相關配置庫函數

  • 2個模式進入函數
  1.  
    void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
  2.  
    void PWR_EnterSTANDBYMode(void);

作用:前者進入停機狀態,后者進入待機狀態。

  • 2個使能函數
  1.  
    void PWR_WakeUpPinCmd(FunctionalState NewState);
  2.  
    void PWR_BackupAccessCmd(FunctionalState NewState);

作用:前者使能WK_UP引腳喚醒(正常模式下,WK_UP引腳作為普通IO口,待機模式下設置成喚醒功能),后者使能BKP后備區域訪問使能。

  • 2個狀態位函數
  1.  
    FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
  2.  
    void PWR_ClearFlag(uint32_t PWR_FLAG);

作用:前者獲取電源控制的狀態位,后者清除相應的狀態位。

  • 2個內核指令函數
  1.  
    __WFI();
  2.  
    __WFE();

作用:CM3內核的WFI(等待中斷)、WFE(等待事件)指令(定義在:core_cm3.h)。

 

待機模式的一般步驟

實例要求:實現同一個引腳PA0引腳(WK_UP引腳),正常模式下,長按3秒進入待機模式;待機模式下,長按3秒待機喚醒。

  • 使能電源時鍾。調用函數:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  • 設置WK_UP引腳作為喚醒源。調用函數:PWR_WakeUpPinCmd(ENABLE);
  • 進入待機模式。調用函數:void PWR_EnterSTANDBYMode(void),執行設置SLEEPDEEP位,設置PDDS位,執行WFI指令。
#define WKUP_KD PAin(0) //PA0 檢測是否外部WK_UP按鍵按下
  1.  
    void Sys_Standby(void)
  2.  
    {
  3.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外設時鍾
  4.  
    PWR_WakeUpPinCmd(ENABLE); //使能喚醒管腳功能
  5.  
    PWR_EnterSTANDBYMode(); //進入待命(STANDBY)模式
  6.  
    }
  7.  
    //系統進入待機模式
  8.  
    void Sys_Enter_Standby(void)
  9.  
    {
  10.  
    RCC_APB2PeriphResetCmd( 0X01FC,DISABLE); //復位所有IO口
  11.  
    Sys_Standby();
  12.  
    }
  13.  
    //檢測WKUP腳的信號
  14.  
    //返回值1:連續按下3s以上
  15.  
    // 0:錯誤的觸發
  16.  
    u8 Check_WKUP( void)
  17.  
    {
  18.  
    u8 t= 0; //記錄按下的時間
  19.  
    LED0= 0; //亮燈DS0
  20.  
    while(1)
  21.  
    {
  22.  
    if(WKUP_KD)
  23.  
    {
  24.  
    t++; //已經按下了
  25.  
    delay_ms( 30);
  26.  
    if(t>=100) //按下超過3秒鍾
  27.  
    {
  28.  
    LED0= 0; //點亮DS0
  29.  
    return 1; //按下3s以上了
  30.  
    }
  31.  
    } else
  32.  
    {
  33.  
    LED0= 1;
  34.  
    return 0; //按下不足3秒
  35.  
    }
  36.  
    }
  37.  
    }
  38.  
    //中斷,檢測到PA0腳的一個上升沿.
  39.  
    //中斷線0線上的中斷檢測
  40.  
     
  41.  
     
  42.  
    void EXTI0_IRQHandler(void)
  43.  
    {
  44.  
    EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中斷標志位
  45.  
    if(Check_WKUP())//關機?
  46.  
    {
  47.  
    Sys_Enter_Standby();
  48.  
    }
  49.  
    }
  50.  
    //PA0 WKUP喚醒初始化
  51.  
    void WKUP_Init(void)
  52.  
    {
  53.  
    GPIO_InitTypeDef GPIO_InitStructure;
  54.  
    NVIC_InitTypeDef NVIC_InitStructure;
  55.  
    EXTI_InitTypeDef EXTI_InitStructure;
  56.  
     
  57.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOA和復用功能時鍾
  58.  
     
  59.  
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; //PA.0
  60.  
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD; //上拉輸入
  61.  
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO
  62.  
    //使用外部中斷方式
  63.  
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //中斷線0連接GPIOA.0
  64.  
     
  65.  
    EXTI_InitStructure.EXTI_Line = EXTI_Line0; //設置按鍵所有的外部線路
  66.  
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //設外外部中斷模式:EXTI線路為中斷請求
  67.  
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿觸發
  68.  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  69.  
    EXTI_Init(&EXTI_InitStructure); // 初始化外部中斷
  70.  
     
  71.  
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按鍵所在的外部中斷通道
  72.  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占優先級2級
  73.  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //從優先級2級
  74.  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
  75.  
    NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
  76.  
     
  77.  
    if(Check_WKUP()==0) Sys_Standby(); //不是開機,進入待機模式
  78.  
     
  79.  
    }
  1.  
    int main(void)
  2.  
    {
  3.  
     
  4.  
    delay_init(); //延時函數初始化
  5.  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷優先級分組為組2:2位搶占優先級,2位響應優先級
  6.  
    uart_init( 115200); //串口初始化為115200
  7.  
    LED_Init(); //LED端口初始化
  8.  
    WKUP_Init(); //待機喚醒初始化
  9.  
    LCD_Init(); //LCD初始化
  10.  
    POINT_COLOR=RED;
  11.  
     
  12.  
    LCD_ShowString( 30,50,200,16,16,"Warship STM32");
  13.  
    LCD_ShowString( 30,70,200,16,16,"WKUP TEST");
  14.  
    LCD_ShowString( 30,90,200,16,16,"ATOM@ALIENTEK");
  15.  
    LCD_ShowString( 30,110,200,16,16,"2014/1/14");
  16.  
     
  17.  
    while(1)
  18.  
    {
  19.  
    LED0=!LED0;
  20.  
    delay_ms( 250);
  21.  
    }
  22.  
    }

STM32控制程序分析

WKUP_Init()函數:初始化GPIO、外部中斷等准備工作。

由於WK_UP鍵有兩個功能:正常模式下,長按3秒進入待機模式;待機模式下,長按3秒退出待機模式。

本案例中的實現是:

  • 正常模式下,將WK_UP鍵設置成外部中斷,一旦按下,進入中斷處理函數,在中斷處理函數中進行3秒的時間判斷是否進入待機模式;
  1.  
    void WKUP_Init(void)
  2.  
    {
  3.  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOA和復用功能時鍾
  4.  
     
  5.  
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; //PA.0
  6.  
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD; //上拉輸入
  7.  
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO
  8.  
    //使用外部中斷方式
  9.  
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //中斷線0連接GPIOA.0
  10.  
     
  11.  
    EXTI_Init(&EXTI_InitStructure); // 初始化外部中斷
  12.  
     
  13.  
    NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
  14.  
     
  15.  
    }
  1.  
    void EXTI0_IRQHandler(void)
  2.  
    {
  3.  
    EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中斷標志位
  4.  
    if(Check_WKUP())//關機?
  5.  
    {
  6.  
    Sys_Enter_Standby();
  7.  
    }
  8.  
    }
  • 待機模式下,設置WK_UP鍵用來退出待機模式,一旦按下,退出待機模式,重新執行main主函數,在主函數中進行3秒的時間判斷,如果沒有3秒,重新進入待機模式,否則繼續正常執行。
  1.  
    void WKUP_Init(void)
  2.  
    {
  3.  
             //初始化過程
  4.  
    if(Check_WKUP()==0) Sys_Standby(); //不是開機,進入待機模式
  5.  
     
  6.  
    }

而其中進入待機模式的程序代碼塊,就是之前的待機模式的一般步驟:

  1.  
    void Sys_Standby(void)
  2.  
    {
  3.  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外設時鍾
  4.  
    PWR_WakeUpPinCmd(ENABLE); //使能喚醒管腳功能
  5.  
    PWR_EnterSTANDBYMode(); //進入待命(STANDBY)模式
  6.  
    }
     
     
     
     
    重要:在待機模式下,PA0喚醒,reset重跑main 按下按鍵3s,需要判斷標志位,不然在待機模式下斷電后重啟,會無法正常:
    代碼:PWR_GetFlagStatus (PWR_FLAG_SB)。
     
     


免責聲明!

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



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