1.STM32待機模式介紹
? 很多單片機具有低功耗模式,比如MSP430、STM8L等,我們的STM32也不例外。默認情況下,系統復位或上電復位后,微控制器進入運行模式。在運行模式下,HCLK 為CPU提供時鐘,并執行程序代碼。這是正常的一般運行模式。
而當 CPU 不需繼續運行(例如等待外部事件)時,可以利用多種低功耗模式來節省功耗。用戶需要根據最低電源消耗、最快速啟動時間和可用的喚醒源等條件,選定一個最佳的低功耗模式。
? 當然在運行模式下,也可以通過如下方式降低功耗:
(1)降低系統時鐘速度
(2)不使用 APBx 和 AHB 外設時,將對應的外設時鐘關閉
STM32 提供了 3 種低功耗模式,以達到不同層次的降低功耗的目的,這三種模式如下:
(1)睡眠模式( CM3 內核停止工作,外設仍在運行)
(2)停止模式(所有時鐘都停止)
(3)待機模式( 1.8 V 內核電源關閉)
?? 這三種模式所需的功耗是逐級遞減,也就是說待機模式功耗是最低的。三種低功耗模式匯總表如圖所示:?
? ?????????
本章我們僅對STM32的待機模式進行介紹,其他2種模式可以參考《STM32F10x中文參考手冊》-4電源控制器(PWR)章節,里面有詳細的介紹。
?在睡眠模式中,僅關閉了內核時鐘,內核停止運行,但其片上外設, CM3 核心的外設全都照常運行。
在停止模式中,進一步關閉了其它所有的時鐘,于是所有的外設都停止了工作,但由于其 1.8V 區域的部分電源沒有關閉,還保留了內核的寄存器、內存的信息,所以從停止模式喚醒,并重新開啟時鐘后,還可以從上次停止處繼續執行代碼。
在待機模式中,它除了關閉所有的時鐘,還把 1.8V 區域的電源也完全關閉了,也就是說,從待機模式喚醒后,由于沒有之前代碼的運行記錄,只能對芯片復位,重新檢測BOOT條件,從頭開始執行程序。
那么我們如何進入待機模式呢?其實很簡單,只要按下圖所示的步驟執行就可以了。
? 從待機模式喚醒后,程序將按照復位(啟動引腳采樣、復位向量已獲取等)后的方式重新執行。電源控制/狀態寄存器(PWR_CSR)將會指示內核由待機狀態退出。
? 在進入待機模式后,除了復位引腳以及被設置為防侵入或校準輸出時的 TAMPER (PC13)引腳和被使能的喚醒引腳( WK_UP 腳(PA0)),其他的 IO 引腳都將處于高阻態。
2.待機模式配置步驟
? 接下來我們介紹下如何使用庫函數進入和退出待機模式。這個也是在編寫程序中必須要了解的。具體步驟如下:(電源管理相關庫函數在stm32f10x_pwr.c和stm32f10x_pwr.h文件中)
(1)使能電源時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
(2)設置WK_UP引腳為喚醒源
PWR_WakeUpPinCmd(ENABLE);
(3)進入待機模式
PWR_EnterSTANDBYMode();//進入待機模式
PWR_ClearFlag(PWR_FLAG_WU);//清除Wake-up 標志??????????
3.硬件電路
? 本實驗使用到硬件資源如下:
(1)D1指示燈
(2)串口1
(3)K_UP按鍵
D1指示燈用來提示系統正常運行,K_UP按鍵用來喚醒待機模式,串口1用來輸出提示信息。
4.編寫待機喚醒程序
? 本實驗所要實現的功能是:系統運行時D1指示燈閃爍,5秒后進入待機模式,D1指示燈熄滅,同時串口printf輸出相關提示信息,通過K_UP按鍵實現喚醒。程序框架如下:
(1)配置進入與退出待機模式
(2)編寫主函數
main.c
#include "system.h"
#include "led.h"
#include "SysTick.h"
#include "usart.h"
#include "input.h"
#include "wakeup.h"int main()
{u8 i;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中斷優先級分組LED_Init();USART1_Init(9600);while(1){for (i=9;i>0;i--){printf("time:=%d\r\n",i);led1=!led1;delay_ms(1000);}printf("進入待機模式\r\n");delay_ms(1000);Enter_StandbyMode();}
}
wakeup.c
#include "wakeup.h"void Enter_StandbyMode()
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//1)使能電源時鐘PWR_WakeUpPinCmd(ENABLE);//(2)設置WK_UP引腳為喚醒源PWR_ClearFlag(PWR_FLAG_WU);//清除Wake-up 標志PWR_EnterSTANDBYMode();//進入待機模式}
?wakeup.h
#ifndef _wakeup_H
#define _wakeup_H#include "system.h"void Enter_StandbyMode(void);#endif
? 以上程序燒錄到開發板上測試,結果如下。實驗是成功的。
??