【STM32+cubemx】0014 HAL庫開發:電源控制(三種低功耗模式:sleep、stop、standby)


本節我們來講一講stm32的電源控制,也就是低功耗模式。

1)stm32的低功耗模式簡介

stm32有三種低功耗模式,功耗依次降低:

睡眠模式(sleep mode),停止模式(stop mode),待機模式(standby mode)。

睡眠模式:只有內核時鍾關閉,外設仍在運行;可以通過任意一個中斷或喚醒事件喚醒;喚醒后回到睡眠的位置向后執行。

停止模式:關閉內核時鍾、外設時鍾,保留內核1.8V供電,寄存器和RAM中的數據可以保持,IO口狀態也可保持;可以通過任意一個外部中斷喚醒;喚醒后可回到停止的代碼處向后執行,但要重新初始化時鍾和外設。

待機模式:關閉所有時鍾,關閉內核1.8V供電,寄存器和RAM數據不能保持(除了電源控制/狀態寄存器(PWR_CSR)、備份寄存器,其他數據都丟失);可通過喚醒引腳(PA0)上升沿、RTC鬧鍾中斷,或者復位喚醒;喚醒后相當於復位,從復位地址開始執行。

三種模式的特性匯總如下表:

當stm32執行WFI(等待中斷)或WFE(等待事件)指令后,即進入低功耗模式,這是兩條匯編指令,實際使用時,HAL庫已經為我們封裝好了函數,只需要調用相應的C語言函數即可。

2)低功耗模式的使用

我們仍然以串口的工程為基礎,在它上面添加設置,如下圖,先設置外部中斷:

再設置RTC:

注意添加的有:

RTC中,勾選active clock source、勾選active calendar;

勾選RTC alarm interrupt through EXTI line 17中斷,這里注意一下,有的cubemx版本起初這個RTC alarm中斷顯示不出來,需要選一下上面的RTC OUT,選為輸出,然后這個中斷就顯示出來了,之后再選擇為無輸出也還在;

選上PA0為喚醒引腳、PA1為外部中斷1。

低功耗模式本身不需要特殊設置,生成HAL庫工程文件時都會自帶;這里選上RTC alarm中斷、喚醒引腳、外部中斷1,都是為了之后試驗將cpu從低功耗模式中喚醒。

生成工程代碼,在keil中打開。Stm32的hal庫中已經封裝好了低功耗模式的函數,但是為了便於使用我們自己需要的喚醒功能、實現我們需要的功耗控制,一般會把函數再封裝一次。

a)sleep模式的使用

先看sleep模式的使用,進入sleep模式的代碼如下:

因為所有的中斷都能喚醒sleep模式,所以在進入sleep模式前,需要關閉systick中斷,因為systick每1ms會產生一次中斷,如果不關閉,則sleep模式會很快自動退出來;

接着是調用HAL庫函數,進入sleep模式;

最后是恢復systick中斷,這一步是為了在sleep模式被喚醒后,恢復原有的系統systick節拍。

之后,就可以調用這個函數,來進入sleep模式了。

由於sleep模式只是內核時鍾關閉,外設是仍然在運行的,所以喚醒后系統的狀態還和進入低功耗模式前一樣。

b)stop模式的使用

stop模式使用時,進入stop模式的代碼如下:

這里我們設置使用PA0為喚醒引腳,所以先清除它的中斷標志;再調用HAL庫函數進入stop模式。

之后就可以調用它來進入stop模式了。

但是要注意的一點是,stop模式被喚醒后,時鍾默認使用的是內部RC振盪器,外設的時鍾也被關閉了,所以要重新初始化時鍾和外設,這部分功能,我們編寫一個函數來實現:

(這里為了實現簡單,把main函數初始化的一部分拷貝過來了,實際上有些函數可以簡化)

這樣,需要進入stop模式時,我們直接如下調用者兩個函數即可:

enter_stop_mode();

exit_stop_mode();

enter_stop_mode()函數進入stop模式,設置PA0作為喚醒功能;被喚醒后,回到exit_stop_mode()處執行,恢復內核與外設時鍾,再執行后面的其他程序。

c)standby模式的使用

standby模式使用時,進入standby模式的代碼如下:

與stop模式是類似的,也是設置使用PA0為喚醒引腳,所以先清除它的中斷標志;再調用HAL庫函數進入standby模式。

由於standby模式被喚醒后,會從程序起始處開始執行,相當於復位,main函數的初始化程序都會再執行一遍,所以不用對退出standby模式作處理。使用時直接調用enter_standby_mode()函數即可。

此外,可以通過在程序起始時,判斷電源控制/狀態寄存器(PWR_CSR)的狀態,來識別是從standby模式被喚醒的,還是系統被復位了,主要的代碼如下:

3)低功耗和喚醒試驗

現在我們來試驗一下這幾種低功耗模式的進入和喚醒。

在這之前,我們先編寫一個RTC alarm的函數,使得可以方便地設置RTC鬧鍾時間,使用RTC喚醒,代碼如下:

這個函數實現的功能是,先讀取當年前的RTC時間,再將鬧鍾時間設置到當前時間加nsecond秒之后,然后啟動RTC alarm中斷,這樣就能方便地設置到nsecond秒后產生RTC alarm中斷。

在Main函數的主循環中添加如下測試sleep模式的代碼:

先設置10s后RTC alarm中斷,然后進入sleep模式;由於在生成工程時,我們還設置了外部中斷PA1;所以,只要RTC計時達到10s、或者PA1上有下降沿,都會觸發中斷,退出sleep模式;退出之后,還進行了關閉RTC alarm中斷的操作。程序運行結果如下圖所示:

再試驗stop模式,添加如下代碼:

同樣是開啟10s后RTC中斷,之后進入stop模式;退出stop模式后,也進行了關閉RTC alarm中斷的操作。

這段程序運行時,stop模式也是能被RTC alarm、PA1(外部中斷1)喚醒的,同時,由於我們設置了喚醒引腳PA0,在PA0上的上升沿也能喚醒。程序運行如下:

Standby模式試驗,代碼如下:

注意standby模式下,喚醒之后是類似復位,到程序的起始地址去執行了;

printf("fail to standby mode\t%d\r\n",count++);這一句,正常情況下是執行不到這里的。

這段代碼運行的結果如下,可以看到,從standby模式中被喚醒后,沒有執行之后的語句,而是“復位”了:

4)stm32的低功耗使用注意事項

a)程序起始時建議延時幾秒再進入低功耗模式,否則一進入就不能使用下載口了,程序下載會很不方便;設置延時幾秒再進,在上電之后幾秒內完成下載就不會有問題;或者SWD接口之外,再連上復位線;

b)不用的IO口設置為模擬輸入態最省電;cubemx里可以如下圖設置,進入定低功耗模式前,將特殊的幾個單獨設置一下;

c)中斷輸入的引腳如果有上下拉,則會消耗電流;

d)如果外部晶振不使用,必須將引腳配置為輸入上拉、下拉或者輸出低電平,配置為浮空輸入會消耗極大的電流(200uA);

e)輸入引腳,如果高阻狀態端口是高電平,就設成上拉輸入,如果高阻狀態是低電平,設成下拉輸入,如果高阻是中間狀態,設成模擬輸入;輸出引腳會耗電,如果可以盡量不用;

f)進入stop模式前,不要將pwr的clk關閉,實際測試關閉能用,也能喚醒,但是電流會增加10uA;實際上stop模式會關閉外設和內核時鍾,不用單獨去關閉其他外設的時鍾;

g)在運行模式下、或者sleep模式下,由於時鍾是還在的,降低時鍾可以降低功耗。

歡迎關注我的公眾號,可留言“資料”獲取相關資料和代碼:


免責聲明!

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



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