PWR和低功耗模式
PWR簡介
- PWR(Power Control) 電源控制
- PWR負責管理STM32內部的電源供電部分,可以實現可編程電壓檢測器和低功耗模式的功能
- 可編程電壓檢測器(PVD) 可以監控VDD電源電壓,當VDD下降到PVD閾值以下或上升到PVD閾值之上時,PVD會觸發中斷,用于執行緊急關閉任務
- 低功耗模式包括睡眠模式(Sleep)、停機模式(Stop)和待機模式(Standby),可在系統空閑時,降低STM32的功耗,延長設備使用時間
電源框圖
- V D D 、 V S S V_{DD}、V_{SS} VDD?、VSS?給數字電路供電
- V D D A 、 V S S A V_{DDA}、V_{SSA} VDDA?、VSSA?給模擬電路供電
- 低電壓檢測器在檢測到 V D D 和 V S S V_{DD}和V_{SS} VDD?和VSS?之間電壓低于閾值后,會切換后備供電區域的供電電源為 V B A T V_{BAT} VBAT?,而當 V D D 和 V S S V_{DD}和V_{SS} VDD?和VSS?供電正常時,則由 V D D 和 V S S V_{DD}和V_{SS} VDD?和VSS?供電
- 芯片內部的數字電路(1.8V供電區域)供電電壓為1.8V
- 關于 V D D A 和 V S S A V_{DDA}和V_{SSA} VDDA?和VSSA?的作用參考手冊, 注意在STM32F103C8T6中未引出
上電復位和掉電復位
可編程電壓檢測器
低功耗模式
- 一般使用
WFI (wait for interrupt)
等待中斷 睡眠模式(Sleep Mode)
下, 任一中斷都可以喚醒MCU,一般省電停機模式(Stop Mode)
下,僅外部中斷能夠喚醒MCU,同時1.8V區域的時鐘全部關閉,HSI和HSE的時鐘也關閉,但電壓調節器仍然打開,SRAM和寄存器中的數據不會丟失待機模式(Standby Mode)
下,僅特定事件能夠喚醒MCU,相較于停機模式
電壓調節器關閉,SRAM和寄存器中數據丟失Sleep Mode
和Stop Mode
喚醒后程序從進入低功耗模式的代碼開始重新執行,而Standby Mode
喚醒后程序從頭開始執行(因為數據都丟失了)- 值的注意的是,
Stop Mode
喚醒后默認使用HSI (8MHz)
作為系統時鐘, 若想用HSE
則需重新調用SystemInit()
函數
模式選擇
- 對照該圖和參考手冊配置自己需要的模式
睡眠模式
-
執行完WFI/WFE指令后,STM32進入睡眠模式,程序暫停運行,喚醒后程序從暫停的地方繼續運行
-
SLEEPONEXIT位決定STM32執行完WFI或WFE后,是立刻進入睡眠,還是等STM32從最低優先級的中斷處理程序中退出時進入睡眠 (WFI或WFE寫主函數里立刻進入睡眠還是先處理中斷差別不大)
-
在睡眠模式下,所有的I/O引腳都保持它們在運行模式時的狀態 (為進一步降低能耗,在執行WFI/WFE前關閉能關閉的外設)
-
WFI指令進入睡眠模式,可被任意一個NVIC響應的中斷喚醒
-
WFE指令進入睡眠模式,可被喚醒事件喚醒
停止模式
-
執行完WFI/WFE指令后,STM32進入停止模式,程序暫停運行,喚醒后程序從暫停的地方繼續運行
-
1.8V供電區域的所有時鐘都被停止,PLL、HSI和HSE被禁止,SRAM和寄存器內容被保留下來
-
在停止模式下,所有的I/ O引腳都保持它們在運行模式時的狀態 (為進一步降低能耗,在執行WFI/WFE前關閉能關閉的外設)
-
當一個中斷或喚醒事件導致退出停止模式時,HSI被選為系統時鐘
-
當電壓調節器處于低功耗模式下,系統從停止模式退出時,會有一段額外的啟動延時
-
WFI指令進入停止模式,可被任意一個EXTI中斷喚醒 (RTC和PVD可借道EXTI中斷通道將MCU從停止模式喚醒)
待機模式
-
執行完WFI/WFE指令后,STM32進入待機模式,喚醒后程序從頭開始運行
-
整個1.8V供電區域被斷電,PLL、HSI和HSE也被斷電,SRAM和寄存器內容丟失,只有備份的寄存器和待機電路維持供電
-
在待機模式下,所有的I/O引腳變為高阻態(浮空輸入)(不用手動關閉外設)
-
WKUP引腳的上升沿、RTC鬧鐘事件的上升沿、NRST引腳上外部復位、IWDG復位退出待機模式
降低系統主頻和關閉APB和AHB總線上未被使用的外設時鐘
- 除了低功耗模式能降低電源消耗外,降低系統主頻和關閉未使用的外設時鐘也是降低電源消耗的很好的方式
- 系統主頻通過時鐘樹可以看出,由
HSE
接外部晶振提供(一般8MHz),經過PLL
得到倍頻,然后作為系統主頻
-
關于系統主頻的修改,相關的文件是
system_stm32f10x.c
,通過宏定義可修改成以下時鐘頻率, 具體函數的執行流程可以自己看或看江科大的視頻
-
如何取消只讀文件的限制
打開文件屬性,取消可讀后確定
文件上的鑰匙消失,現在可以修改文件中關于主頻的宏定義
主要代碼
功能為單片機運行10s即進入停止模式, 當檢測到外部中斷后, 退出停止模式, 運行10s后再次進入停止模式
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"
#include "key.h"
#include "LED.h"
#include "Timer.h"
#include "valve.h"uint8_t Stop_Time;int main(void)
{OLED_Init();MyRTC_Init(); // RTC初始化Key_Init(); // 按鍵初始化LED_Init(); // LED 初始化Timer_TIM3_Init(); // 定時器初始化Valve_Init(); // 電磁閥端口初始化RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // 打開PWR時鐘 *OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");Stop_Time = 0;while (1){MyRTC_ReadTime();OLED_ShowNum(1, 6, MyRTC_Time[0], 4);OLED_ShowNum(1, 11, MyRTC_Time[1], 2);OLED_ShowNum(1, 14, MyRTC_Time[2], 2);OLED_ShowNum(2, 6, MyRTC_Time[3], 2);OLED_ShowNum(2, 9, MyRTC_Time[4], 2);OLED_ShowNum(2, 12, MyRTC_Time[5], 2);OLED_ShowNum(3, 1, Stop_Time, 3);if(Stop_Time > 100){Stop_Time = 0;OLED_Clear(); // 屏幕熄滅RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, DISABLE); // 關閉GPIOB時鐘PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI); // 進入停止模式*SystemInit(); // 重新設置時鐘OLED_Init();Valve_Init(); // 電磁閥端口初始化OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");}}
}/**
* @brief 按鍵中斷服務函數 PA8
*/
void EXTI9_5_IRQHandler(void)
{if(EXTI_GetFlagStatus(EXTI_Line8)){Delay_ms(10);if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0){LED_Turn();}EXTI_ClearITPendingBit(EXTI_Line8);}
}/**
* @brief 定時器中斷服務函數 TIM3_UpDate
*/
void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3, TIM_IT_Update)){Stop_Time += 1;}TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
- 要進入停止模式只需通過
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
打開PWR時鐘 - 再在需要進入停止模式的時候調用
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
即可進入停止模式 - 進入停止模式前,根據需求關閉耗電的外設
- 從停止模式退出后,系統使用HSI時鐘主頻默認為
8Mhz
, 需重新調用SystemInit()
函數重新設置時鐘為HSE使主頻恢復為72MHz
- 從停止模式退出后,應重新初始化關閉的外設
效果展示
【STM32停止模式】
參考資料
模式退出后,系統使用HSI時鐘主頻默認為8Mhz
, 需重新調用SystemInit()
函數重新設置時鐘為HSE使主頻恢復為72MHz
- 從停止模式退出后,應重新初始化關閉的外設