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