????本文我們來學(xué)習(xí)下STM32的待機喚醒功能。要實現(xiàn)的功能是:系統(tǒng)運行時 D1 指示燈閃爍,5 秒后進入待機模式,D1 指示燈熄滅,同時串口 printf輸出相關(guān)提示信息,可通過 K_UP 按鍵實現(xiàn)喚醒。學(xué)習(xí)本內(nèi)容可以參考《STM32F10x中文參考手冊》-4 電源控制器(PWR)章節(jié)。
STM32 低功耗模式介紹
????很多單片機具有低功耗模式,比如 MSP430、STM8L等。我們的STM32也不例外,相關(guān)文章:STM32低功耗模式。默認情況下,系統(tǒng)復(fù)位或上電復(fù)位后,微控制器進入運行模式。在運行模式下,HCLK 為 CPU 提供時鐘,并執(zhí)行程序代碼。當 CPU 不需繼續(xù)運行(例如等待外部事件)時,可以利用多種低功耗模式來節(jié)省功耗。用戶需要根據(jù)最低電源消耗、最快速啟動時間和可用的喚醒源等條件,選定一個最佳的低功耗模式。
????當然在運行模式下,也可以通過如下方式降低功耗:
(1)降低系統(tǒng)時鐘速度
(2)不使用 APBx 和 AHB 外設(shè)時,將對應(yīng)的外設(shè)時鐘關(guān)閉
????STM32 提供了 3 種低功耗模式,以達到不同層次的降低功耗的目的,這三
種模式如下:
(1)睡眠模式( CM3 內(nèi)核停止工作,外設(shè)仍在運行)
(2)停止模式(所有時鐘都停止)
(3)待機模式( 1.8 V 內(nèi)核電源關(guān)閉)
????這三種模式所需的功耗是逐級遞減,也就是說待機模式功耗是最低的。三種低功耗模式匯總表如下圖所示:
????我們僅對 STM32 的待機模式進行介紹,其他 2 種模式可以參考《STM32F10x 中文參考手冊》-4電源控制器(PWR)章節(jié),里面有詳細的介紹。
(1)待機模式
????在睡眠模式中,僅關(guān)閉了內(nèi)核時鐘,內(nèi)核停止運行,但其片上外設(shè), CM3 核心的外設(shè)全都照常運行。在停止模式中,進一步關(guān)閉了其它所有的時鐘,于是所有的外設(shè)都停止了工作,但由于其 1.8V 區(qū)域的部分電源沒有關(guān)閉,還保留了內(nèi)核的寄存器、內(nèi)存的信息,所以從停止模式喚醒,并重新開啟時鐘后,還可以從上次停止處繼續(xù)執(zhí)行代碼。在待機模式中, 它除了關(guān)閉所有的時鐘, 還把 1.8V 區(qū)域的電源也完全關(guān)閉了,也就是說,從待機模式喚醒后,由于沒有之前代碼的運行記錄,只能對芯片復(fù)位,重新檢測 BOOT 條件,從頭開始執(zhí)行程序。低功耗開發(fā)相關(guān)文章:STM32低功耗開發(fā)時,需要注意的GPIO配置問題。
????那么我們?nèi)绾芜M入待機模式呢?其實很簡單,只要按下圖所示待機模式進入與退出步驟的步驟執(zhí)行就可以了。
????上圖還列出了退出待機模式的操作,當檢測到外部復(fù)位(NRST 引腳)、
IWDG 復(fù)位、 WKUP 引腳上升沿、 RTC 鬧鐘事件的上升沿時,微控制器退出待機模式。本文我們是通過 WKUP 引腳(PA0)上升沿來退出待機模式,當然也可以直接通過芯片復(fù)位管腳 NRST退出。
????從待機模式喚醒后,除了電源控制/狀態(tài)寄存器(PWR_CSR),所有的寄存器豆被復(fù)位,程序?qū)凑諒?fù)位(啟動引腳采樣、復(fù)位向量已獲取等)后的方式重新執(zhí)行。電源控制/狀態(tài)寄存器(PWR_CSR)將會指示內(nèi)核由待機狀態(tài)退出。
????在進入待機模式后,除了復(fù)位引腳以及被設(shè)置為防侵入或校準輸出時的
TAMPER (PC13)引腳和被使能的喚醒引腳( WK_UP 腳(PA0)),其他的 IO 引腳都將處于高阻態(tài)。
????由于篇幅限制,本文并沒有對待機模式相關(guān)寄存器進行介紹,大家可以參考《STM32F10x 中文參考手冊》-4 電源控制器(PWR)章節(jié),里面有詳細的講解。如果看不懂的可以暫時放下,因為我們使用的是庫函數(shù)開發(fā)。
待機模式配置步驟
????接下來我們介紹下如何使用庫函數(shù)進入和退出待機模式。這個也是在編寫程序中必須要了解的。
????具體步驟如下:(電源管理相關(guān)庫函數(shù)在 stm32f10x_pwr.c和 stm32f10x_pwr.h 文件中)
(1)使能電源時鐘
????因為低功耗模式是通過 STM32 電源(PWR)系統(tǒng)進行管理的,所以需要使能電源時鐘,調(diào)用的庫函數(shù)為:
?
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能?PWR?外設(shè)時鐘
?
(2)設(shè)置 WK_UP 引腳為喚醒源
????待機喚醒方式有很多種,我們選擇 WK_UP 引腳(PA0)上升沿來退出待機模式。在庫函數(shù)中,設(shè)置使能 WK_UP 用于喚醒 CPU 待機模式的函數(shù)是:
?
PWR_WakeUpPinCmd(ENABLE);
?
????因為按鍵 K_UP 連接在PA0 管腳上,并且是高電平有效,這樣一來就可以使用 K_UP按鍵來退出待機模式。
(3)進入待機模式
????進入待機模式, 首先要設(shè)置 SLEEPDEEP 位 ( 詳見 《 Cortex M3 權(quán)威指南(中文)》 , chpt13 Cortex-M3 的其它特性--電源管理章節(jié)) ,接著我們通過 PWR_CR設(shè)置 PDDS 位,使得 CPU 進入深度睡眠時進入待機模式,最后執(zhí)行 WFI 指令開始進入待機模式,并等待 WK_UP 中斷的到來。整個操作可以通過一個庫函數(shù)完成,如下:
?
PWR_EnterSTANDBYMode();//進入待機模式
?
????通常在進入待機模式前,我們會清除喚醒標志,以等待下次進入。清除喚醒標志庫函數(shù)為:
?
PWR_ClearFlag(PWR_FLAG_WU);//清除 Wake-up 標志
?
????以上幾步全部配置好后,我們就可以正常進入待機模式了,并且可以通過按鍵 K_UP或者復(fù)位按鍵喚醒。
????特別提醒下,如果學(xué)到 RTC 實時時鐘實驗的時候,需要進入待機模式,如果使能了 RTC 鬧鐘中斷的時候,進入待機模式前,必須按如下操作處理:
1.禁止 RTC 中斷( ALRAIE、 ALRBIE、 WUTIE、 TAMPIE 和 TSIE 等)。
2.清零對應(yīng)中斷標志位。
3.清除 PWR 喚醒(WUF)標志(通過設(shè)置 PWR_CR 的 CWUF 位實現(xiàn))。
4.重新使能 RTC 對應(yīng)中斷。
5.進入低功耗模式。
????本實驗使用到硬件資源如下:
(1)D1 指示燈
(2)串口 1
(3)K_UP 按鍵
??? D1指示燈、K_UP 按鍵、串口 1 電路在前面章節(jié)都介紹過,這里不多說。D1指示燈用來提示系統(tǒng)正常運行,K_UP 按鍵用來喚醒待機模式,串口 1 用來輸出提示信息。
????所要實現(xiàn)的功能是:系統(tǒng)運行時 D1 指示燈閃爍,5 秒后進入待機模式,D1 指示燈熄滅,同時串口 printf 輸出相關(guān)提示信息,通過 K_UP 按鍵實現(xiàn)喚醒。
????程序框架如下:
(1)配置進入與退出待機模式
(2)編寫主函數(shù)
????前面介紹待機模式配置步驟時,就已經(jīng)講解如何配置。下面我們打開“待機喚醒實驗”工程,在 APP 工程組中可以看到添加了wkup.c文件(里面包含了待機模式驅(qū)動程序),在 StdPeriph_Driver 工程組中添加了 stm32f10x_pwr.c 庫文件。電源系統(tǒng)管理相關(guān)操作的庫函數(shù)都放在stm32f10x_pwr.c 和 stm32f10x_pwr.h 文件中,所以使用到電源系統(tǒng)管理就必須加入 stm32f10x_pwr.c 文件,同時還要包含對應(yīng)的頭文件路徑。
????這里我們分析幾個重要函數(shù),其他部分程序大家可以打開工程查看。
待機模式配置函數(shù)
????要讓系統(tǒng)進入待機模式,我們必須對它進行配置。進入待機模式代碼如下:
?
/***************************************************************** 函 數(shù) 名 : Enter_Standby_Mode* 函數(shù)功能 : 進入待機模式* 輸 入 : 無* 輸 出 : 無*****************************************************************/void Enter_Standby_Mode(void){??RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能?PWR?外設(shè)時鐘 PWR_ClearFlag(PWR_FLAG_WU);//清除 Wake-up 標志??PWR_WakeUpPinCmd(ENABLE);//使能喚醒管腳?使能或者失能喚醒管腳功能 PWR_EnterSTANDBYMode();//進入待機模式}
?
? ?該函數(shù)首先使能電源PWR時鐘,然后清除喚醒標志位,并使能 WK_UP管腳為喚醒方式,最后進入待機模式。這一過程在前面步驟介紹中已經(jīng)提了。
主函數(shù)
????配置待機模式后,我們就可以編寫主函數(shù),代碼如下:
?
/***************************************************************** 函 數(shù) 名 : main* 函數(shù)功能 : 主函數(shù)* 輸 入 : 無* 輸 出 : 無*****************************************************************/int main(){ SysTick_Init(72);??NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);?//中斷優(yōu)先級分組?分2?組 LED_Init(); USART1_Init(9600); while(1) { printf("time: 5 "); led1=0; delay_ms(1000); //隔 1 秒顯示計數(shù) printf("time: 4 "); led1=1; delay_ms(1000); printf("time: 3 "); led1=0; delay_ms(1000); printf("time: 2 "); led1=1; delay_ms(1000); printf("time: 1 "); led1=0; delay_ms(1000); printf("進入系統(tǒng)待機模式 "); Enter_Standby_Mode(); }}
?
????主函數(shù)實現(xiàn)的功能很簡單,首先調(diào)用之前編寫好的硬件初始化函數(shù),包括
SysTick 系統(tǒng)時鐘,中斷分組,LED 初始化等。然后進入 while 循環(huán),每間隔一秒讓 printf 輸出一個信息,同時指示燈狀態(tài)發(fā)生變化。倒計 5 秒鐘后,調(diào)用函數(shù) Enter_Standby_Mode進入待機模式,此時指示燈熄滅。
????將工程程序編譯后下載到開發(fā)板內(nèi),可以看到系統(tǒng)運行時 D1 指示燈不斷閃爍,5 秒鐘后進入待機模式,此時 D1 指示燈熄滅。當按下 K_UP 按鍵或復(fù)位按鍵時,待機模式被喚醒,系統(tǒng)重新運行,同時串口打印提示信息。如果想在串口調(diào)試助手上看到輸出信息,可以打開“串口調(diào)試助手”,首先勾選下標號 1 DTR 框,然后再取消勾選。這是因為此串口助手啟動時會把系統(tǒng)復(fù)位住, 通過 DTR 狀態(tài)切換下即可。然后設(shè)置好波特率等參數(shù)后,串口助手上即會收到 printf發(fā)送過來的信息。(串口助手上先勾選下標號1 DTR框,然后再取消勾選)如下圖所示。
????實驗說明:下載待機喚醒實驗程序后,若使用普中 ARM 仿真器下載其他的程序會出現(xiàn)報警,這是因為處于低功耗模式時,所有外設(shè)時鐘都已關(guān)閉,所以需要在下載程序前先復(fù)位下系統(tǒng)。
原文標題:STM32實例-待機喚醒實驗
文章出處:【微信公眾號:STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
?
評論
查看更多