第42章 電源管理—實現低功耗—零死角玩轉STM32-F429系列


 

第42章     電源管理—實現低功耗

全套200集視頻教程和1000PDF教程請到秉火論壇下載:www.firebbs.cn

野火視頻教程優酷觀看網址:http://i.youku.com/firege

 

 

 

本章參考數據:《STM32F4xx 中文參考手冊》、《STM32F4xx規格書》、庫說明文檔《stm32f4xx_dsp_stdperiph_lib_um.chm》。

42.1 STM32的電源管理簡介

電源對電子設備的重要性不言而喻,它是保證系統穩定運行的基礎,而保證系統能穩定運行后,又有低功耗的要求。在很多應用場合中都對電子設備的功耗要求非常苛刻,如某些傳感器信息采集設備,僅靠小型的電池提供電源,要求工作長達數年之久,且期間不需要任何維護;由於智慧穿戴設備的小型化要求,電池體積不能太大導致容量也比較小,所以也很有必要從控制功耗入手,提高設備的續行時間。因此,STM32有專門的電源管理外設監控電源並管理設備的運行模式,確保系統正常運行,並盡量降低器件的功耗。

42.1.1 電源監控器

STM32芯片主要通過引腳VDD從外部獲取電源,在它的內部具有電源監控器用於檢測VDD的電壓,以實現復位功能及掉電緊急處理功能,保證系統可靠地運行。

1.    上電復位與掉電復位(POR與PDR)

當檢測到VDD的電壓低於閾值VPORVPDR時,無需外部電路輔助,STM32芯片會自動保持在復位狀態,防止因電壓不足強行工作而帶來嚴重的后果。見圖 421,在剛開始電壓低於VPOR(1.72V)STM32保持在上電復位狀態(PORPower On Reset),當VDD電壓持續上升至大於VPOR時,芯片開始正常運行,而在芯片正常運行的時候,當檢測到VDD電壓下降至低於VPDR閾值(1.68V),會進入掉電復位狀態(PDRPower Down Reset)

421 PORPDR

2.    欠壓復位(BOR)

PORPDR的復位電壓閾值是固定的,如果用戶想要自行設定復位閾值,可以使用STM32BOR功能(Brownout Reset)。它可以編程控制電壓檢測工作在表 421中的閾值級別,通過修改"選項字節"(某些特殊寄存器)中的BOR_LEV位即可控制閾值級別。其復位控制示意圖見圖 422

421 BOR欠壓閾值等級

等級

條件

電壓值

1級欠壓閾值

下降沿

2.19V

上升沿

2.29V

2級欠壓閾值

下降沿

2.50V

上升沿

2.59V

3級欠壓閾值

下降沿

2.83V

上升沿

2.92V

422 BOR復位控制

3.    可編程電壓檢測器PVD

上述PORPDR以及BOR功能都是使用其電壓閾值與外部供電電壓VDD比較,當低於工作閾值時,會直接進入復位狀態,這可防止電壓不足導致的誤操作。除此之外,STM32還提供了可編程電壓檢測器PVD,它也是實時檢測VDD的電壓,當檢測到電壓低於VPVD閾值時,會向內核產生一個PVD中斷(EXTI16線中斷)以使內核在復位前進行緊急處理。該電壓閾值可通過電源控制寄存器PWR_CSR設置。

使用PVD可配置8個等級,見表 422。其中的上升沿和下降沿分別表示類似圖 422VDD電壓上升過程及下降過程的閾值。

422 PVD的閾值等級

閾值等級

條件

最小值

典型值

最大值

單位

級別0

上升沿

2.09

2.14

2.19

V

下降沿

1.98

2.04

2.08

V

級別1

上升沿

2.23

2.3

2.37

V

下降沿

2.13

2.19

2.25

V

級別2

上升沿

2.39

2.45

2.51

V

下降沿

2.29

2.35

2.39

V

級別3

上升沿

2.54

2.6

2.65

V

下降沿

2.44

2.51

2.56

V

級別4

上升沿

2.7

2.76

2.82

V

下降沿

2.59

2.66

2.71

V

級別5

上升沿

2.86

2.93

2.99

V

下降沿

2.65

2.84

3.02

V

級別6

上升沿

2.96

3.03

3.1

V

下降沿

2.85

2.93

2.99

V

級別7

上升沿

3.07

3.14

3.21

V

下降沿

2.95

3.03

3.09

V

42.1.2 STM32的電源系統

為了方便進行電源管理,STM32把它的外設、內核等模塊跟據功能划分了供電區域,其內部電源區域划分見圖 423

423 STM32的電源系統

從框圖了解到,STM32的電源系統主要分為備份域電路、內核電路以及ADC電路三部分,介紹如下:

    備份域電路

STM32LSE振盪器、RTC、備份寄存器及備份SRAM這些器件被包含進備份域電路中,這部分的電路可以通過STM32VBAT引腳獲取供電電源,在實際應用中一般會使用3V的鈕扣電池對該引腳供電。

在圖中備份域電路的左側有一個電源開關結構,它的功能類似圖 424中的雙二極管,在它的上方連接了VBAT電源,下方連接了VDD主電源(一般為3.3V),右側引出到備份域電路中。當VDD主電源存在時,由於VDD電壓較高,備份域電路通過VDD供電,當VDD掉電時,備份域電路由鈕扣電池通過VBAT供電,保證電路能持續運行,從而可利用它保留關鍵數據。

424 雙二極管結構

    調壓器供電電路

STM32的電源系統中調壓器供電的電路是最主要的部分,調壓器為備份域及待機電路以外的所有數字電路供電,其中包括內核、數字外設以及RAM,調壓器的輸出電壓約為1.2V,因而使用調壓器供電的這些電路區域被稱為1.2V域。

調壓器可以運行在"運行模式"、"停止模式"以及"待機模式"。在運行模式下,1.2V域全功率運行;在停止模式下1.2V域運行在低功耗狀態,1.2V區域的所有時鍾都被關閉,相應的外設都停止了工作,但它會保留內核寄存器以及SRAM的內容;在待機模式下,整個1.2V域都斷電,該區域的內核寄存器及SRAM內容都會丟失(備份區域的寄存器及SRAM不受影響)

    ADC電源及參考電壓

為了提高轉換精度,STM32ADC配有獨立的電源接口,方便進行單獨的濾波。ADC的工作電源使用VDDA引腳輸入,使用VSSA作為獨立的地連接,VREF引腳則為ADC提供測量使用的參考電壓。

42.1.3 STM32的功耗模式

按功耗由高到低排列,STM32具有運行、睡眠、停止和待機四種工作模式。上電復位后STM32處於運行狀態時,當內核不需要繼續運行,就可以選擇進入后面的三種低功耗模式降低功耗,這三種模式中,電源消耗不同、喚醒時間不同、喚醒源不同,用戶需要根據應用需求,選擇最佳的低功耗模式。三種低功耗的模式說明見表 423。    

423STM32的低功耗模式說明

模式

說明

進入方式

喚醒方式

1.2V區域時鍾的影響

VDD區域時鍾的影響

調壓器

睡眠

內核停止,所有外設包括M4核心的外設,如NVIC、系統時鍾(SysTick)等仍在運行

調用WFI命令

任一中斷

內核時鍾關,對其他時鍾和ADC時鍾無影響

調用WFE命令

喚醒事件

停止

所有的時鍾都已停止

配置PWR_CR寄存器的PDDS +LPDS +SLEEPDEEP

+WFIWFE命令

任一外部中斷( 在外部中斷寄存器中設置)

關閉所有1.2V區域的時鍾

HSIHSE的振盪器關閉

開啟或處於低功耗模式( 依據電源控制寄存器的設定)

待機

1.2V 電源關閉

配置PWR_CR寄存器的PDDS +SLEEPDEEP

+WFIWFE命令

WKUP 引腳的上升沿、RTC鬧鍾事件、NRST 引腳上的外部復位、IWDG 復位

從表中可以看到,這三種低功耗模式層層遞進,運行的時鍾或芯片功能越來越少,因而功耗越來越低。

1.    睡眠模式

在睡眠模式中,僅關閉了內核時鍾,內核停止運行,但其片上外設,CM4核心的外設全都還照常運行。有兩種方式進入睡眠模式,它的進入方式決定了從睡眠喚醒的方式,分別是WFI(wait for interrupt)和WFE(wait for event),即由等待"中斷"喚醒和由"事件"喚醒。睡眠模式的各種特性見表 424。

424 睡眠模式的各種特性

特性

說明

立即睡眠

在執行WFI WFE 指令時立即進入睡眠模式。

退出時睡眠

在退出優先級最低的中斷服務程序后才進入睡眠模式。

進入方式

內核寄存器的SLEEPDEEP = 0 ,然后調用WFIWFE指令即可進入睡眠模式;

另外若內核寄存器的SLEEPONEXIT=0時,進入"立即睡眠"模式,SLEEPONEXIT=1時,進入"退出時睡眠"模式。

喚醒方式

如果是使用WFI指令睡眠的,則可使用任意中斷喚醒;

如果是使用WFE指令睡眠的,則由事件喚醒。

睡眠時

關閉內核時鍾,內核停止,而外設正常運行,在軟件上表現為不再執行新的代碼。這個狀態會保留睡眠前的內核寄存器、內存的數據。

喚醒延遲

無延遲。

喚醒后

若由中斷喚醒,先進入中斷,退出中斷服務程序后,接着執行WFI指令后的程序;若由事件喚醒,直接接着執行WFE后的程序。

2.    停止模式

在停止模式中,進一步關閉了其它所有的時鍾,於是所有的外設都停止了工作,但由於其1.2V區域的部分電源沒有關閉,還保留了內核的寄存器、內存的信息,所以從停止模式喚醒,並重新開啟時鍾后,還可以從上次停止處繼續執行代碼。停止模式可以由任意一個外部中斷(EXTI)喚醒。在停止模式中可以選擇電壓調節器為開模式或低功耗模式,可選擇內部FLASH工作在正常模式或掉電模式。停止模式的各種特性見表 425。

425 停止模式的各種特性

特性

說明

調壓器低功耗模式

在停止模式下調壓器可工作在正常模式或低功耗模式,可進一步降低功耗

FLASH掉電模式

在停止模式下FLASH可工作在正常模式或掉電模式,可進一步降低功耗

進入方式

內核寄存器的SLEEPDEEP =1PWR_CR寄存器中的PDDS=0,然后調用WFIWFE指令即可進入停止模式

PWR_CR 寄存器的LPDS=0時,調壓器工作在正常模式,LPDS=1時工作在低功耗模式;

PWR_CR 寄存器的FPDS=0時,FLASH工作在正常模式,FPDS=1時進入掉電模式

喚醒方式

如果是使用WFI指令睡眠的,可使用任意EXTI線的中斷喚醒;

如果是使用WFE指令睡眠的,可使用任意配置為事件模式的EXTI線事件喚醒。

停止時

內核停止,片上外設也停止。這個狀態會保留停止前的內核寄存器、內存的數據。

喚醒延遲

基礎延遲為HSI振盪器的啟動時間,若調壓器工作在低功耗模式,還需要加上調壓器從低功耗切換至正常模式下的時間,若FLASH工作在掉電模式,還需要加上FLASH從掉電模式喚醒的時間。

喚醒后

若由中斷喚醒,先進入中斷,退出中斷服務程序后,接着執行WFI指令后的程序;若由事件喚醒,直接接着執行WFE后的程序。喚醒后,STM32會使用HIS作為系統時鍾。

3.    待機模式

待機模式,它除了關閉所有的時鍾,還把1.2V區域的電源也完全關閉了,也就是說,從待機模式喚醒后,由於沒有之前代碼的運行記錄,只能對芯片復位,重新檢測boot條件,從頭開始執行程序。它有四種喚醒方式,分別是WKUP(PA0)引腳的上升沿,RTC鬧鍾事件,NRST引腳的復位和IWDG(獨立看門狗)復位。

426 待機模式的各種特性

特性

說明

進入方式

內核寄存器的SLEEPDEEP =1PWR_CR寄存器中的PDDS=1PWR_CR寄存器中的喚醒狀態位WUF=0,然后調用WFIWFE指令即可進入待機模式

喚醒方式

通過WKUP引腳的上升沿,RTC鬧鍾、喚醒、入侵、時間戳事件或NRST引腳外部復位及IWDG復位喚醒。

待機時

內核停止,片上外設也停止;內核寄存器、內存的數據會丟失;除復位引腳、RTC_AF1引腳及WKUP引腳,其它I/O口均工作在高阻態。

喚醒延遲

芯片復位的時間

喚醒后

相當於芯片復位,在程序表現為從頭開始執行代碼。

在以上講解的睡眠模式、停止模式及待機模式中,若備份域電源正常供電,備份域內的RTC都可以正常運行、備份域內的寄存器及備份域內的SRAM數據會被保存,不受功耗模式影響。

42.2 電源管理相關的庫函數及命令

STM32標准庫對電源管理提供了完善的函數及命令,使用它們可以方便地進行控制,本小節對這些內容進行講解。

42.2.1 配置PVD監控功能

PVD可監控VDD的電壓,當它低於閾值時可產生PVD中斷以讓系統進行緊急處理,這個閾值可以直接使用庫函數PWR_PVDLevelConfig配置成前面表 422中說明的閾值等級。

42.2.2 WFI與WFE命令

我們了解到進入各種低功耗模式時都需要調用WFIWFE命令,它們實質上都是內核指令,在庫文件core_cmInstr.h中把這些指令封裝成了函數,見代碼清單 241

代碼清單 421 WFIWFE的指令定義(core_cmInstr.h文件)

1

2 /** \brief Wait For Interrupt

3

4 Wait For Interrupt is a hint instruction that suspends execution

5 until one of a number of events occurs.

6 */

7 #define __WFI __wfi

8

9

10 /** \brief Wait For Event

11

12 Wait For Event is a hint instruction that permits the processor to enter

13 a low-power state until one of a number of events occurs.

14 */

15 #define __WFE __wfe

對於這兩個指令,我們應用時一般只需要知道,調用它們都能進入低功耗模式,需要使用函數的格式"__WFI();"和"__WFE();"來調用(因為__wfi__wfe是編譯器內置的函數,函數內部使用調用了相應的匯編指令)。其中WFI指令決定了它需要用中斷喚醒,而WFE則決定了它可用事件來喚醒,關於它們更詳細的區別可查閱《cortex-CM3/CM4權威指南》了解。

42.2.3 進入停止模式

直接調用WFIWFE指令可以進入睡眠模式,而進入停止模式則還需要在調用指令前設置一些寄存器位,STM32標准庫把這部分的操作封裝到PWR_EnterSTOPMode函數中了,它的定義見代碼清單 402

代碼清單 422 進入停止模式

1 /**

2 * @brief 進入停止模式

3 *

4 * @note 在停止模式下所有I/O的會保持在停止前的狀態

5 * @note 從停止模式喚醒后,會使用HSI作為時鍾源

6 * @note 調壓器若工作在低功耗模式,可減少功耗,但喚醒時會增加延遲

7 * @param PWR_Regulator: 設置停止模式時調壓器的工作模式

8 * @arg PWR_MainRegulator_ON: 調壓器正常運行

9 * @arg PWR_LowPowerRegulator_ON: 調壓器低功耗運行

10 * @param PWR_STOPEntry: 設置使用WFI還是WFE進入停止模式

11 * @arg PWR_STOPEntry_WFI: WFI進入停止模式

12 * @arg PWR_STOPEntry_WFE: WFE進入停止模式

13 * @retval None

14 */

15 void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)

16 {

17 uint32_t tmpreg = 0;

18

19 /* 設置調壓器的模式 ------------*/

20 tmpreg = PWR->CR;

21 /* 清除 PDDS LPDS */

22 tmpreg &= CR_DS_MASK;

23

24 /* 根據PWR_Regulator 的值(調壓器工作模式)配置LPDS,MRLVDSLPLVDS */

25 tmpreg |= PWR_Regulator;

26

27 /* 寫入參數值到寄存器 */

28 PWR->CR = tmpreg;

29

30 /* 設置內核寄存器的SLEEPDEEP */

31 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

32

33 /* 設置進入停止模式的方式-----------------*/

34 if (PWR_STOPEntry == PWR_STOPEntry_WFI) {

35 /* 需要中斷喚醒*/

36 __WFI();

37 } else {

38 /* 需要事件喚醒 */

39 __WFE();

40 }

41 /* 以下的程序是當重新喚醒時才執行的,清除SLEEPDEEP位的狀態*/

42 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);

43 }

這個函數有兩個輸入參數,分別用於控制調壓器的模式及選擇使用WFIWFE停止,代碼中先是根據調壓器的模式配置PWR_CR寄存器,再把內核寄存器的SLEEPDEEP位置1,這樣再調用WFIWFE命令時,STM32就不是睡眠,而是進入停止模式了。函數結尾處的語句用於復位SLEEPDEEP位的狀態,由於它是在WFIWFE指令之后的,所以這部分代碼是在STM32被喚醒的時候才會執行。

要注意的是進入停止模式后,STM32的所有I/O都保持在停止前的狀態,而當它被喚醒時,STM32使用HSI作為系統時鍾(16MHz)運行,由於系統時鍾會影響很多外設的工作狀態,所以一般我們在喚醒后會重新開啟HSE,把系統時鍾設置會原來的狀態。

前面提到在停止模式中還可以控制內部FLASH的供電,控制FLASH是進入掉電狀態還是正常供電狀態,這可以使用庫函數PWR_FlashPowerDownCmd配置,它其實只是封裝了一個對FPDS寄存器位操作的語句,見代碼清單 423。這個函數需要在進入停止模式前被調用,即應用時需要把它放在上面的PWR_EnterSTOPMode之前。

代碼清單 423 控制FLASH的供電狀態

1 /**

2 * @brief 設置內部FLASH在停止模式時是否工作在掉電狀態

3 * 掉電狀態可使功耗更低,但喚醒時會增加延遲

4 * @param NewState:

5 ENABLE:FLASH掉電

6 DISABLE:FLASH正常運行

7 * @retval None

8 */

9 void PWR_FlashPowerDownCmd(FunctionalState NewState)

10 {

11 /*配置FPDS寄存器位*/

12 *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)NewState;

13 }

42.2.4 進入待機模式

類似地,STM32標准庫也提供了控制進入待機模式的函數,其定義見代碼清單 403

代碼清單 424 進入待機模式

1 /**

2 * @brief 進入待機模式

3 * @note 待機模式時,除以下引腳,其余引腳都在高阻態:

4 * -復位引腳

5 * - RTC_AF1 引腳 (PC13) (需要使能侵入檢測、時間戳事件或RTC鬧鍾事件)

6 * - RTC_AF2 引腳 (PI8) (需要使能侵入檢測或時間戳事件)

7 * - WKUP 引腳 (PA0) (需要使能WKUP喚醒功能)

8 * @note 在調用本函數前還需要清除WUF寄存器位

9 * @param None

10 * @retval None

11 */

12 void PWR_EnterSTANDBYMode(void)

13 {

14 /* 擇待機模式 */

15 PWR->CR |= PWR_CR_PDDS;

16

17 /* 設置內核寄存器的SLEEPDEEP */

18 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

19

20 /* 存儲操作完畢時才能進入待機模式,使用以下語句確保存儲操作執行完畢 */

21

22 __force_stores();

23

24 /* 等待中斷喚醒 */

25 __WFI();

26 }

該函數中先配置了PDDS寄存器位及SLEEPDEEP寄存器位,接着調用__force_stores函數確保存儲操作完畢后再調用WFI指令,從而進入待機模式。這里值得注意的是,待機模式也可以使用WFE指令進入的,如果您有需要可以自行修改;另外,由於這個函數沒有操作WUF寄存器位,所以在實際應用中,調用本函數前,還需要清空WUF寄存器位才能進入待機模式。

在進入待機模式后,除了被使能了的用於喚醒的I/O,其余I/O都進入高阻態,而從待機模式喚醒后,相當於復位STM32芯片,程序重新從頭開始執行。

42.3 PWR—睡眠模式實驗

在本小節中,我們以實驗的形式講解如何控制STM32進入低功耗睡眠模式。

42.3.1 硬件設計

實驗中的硬件主要使用到了按鍵、LED彩燈以及使用串口輸出調試信息,這些硬件都與前面相應實驗中的一致,涉及到硬件設計的可參考原理圖或前面章節中的內容。

42.3.2 軟件設計

本小節講解的是"PWR—睡眠模式"實驗,請打開配套的代碼工程閱讀理解。

1.    程序設計要點

(1)    初始化用於喚醒的中斷按鍵;

(2)    進入睡眠狀態;

(3)    使用按鍵中斷喚醒芯片;

2.    代碼分析
main函數

睡眠模式的程序比較簡單,我們直接閱讀它的main函數了解執行流程,見代碼清單 242

代碼清單 425 睡眠模式的main函數(main.c文件)

1

2 /**

3 * @brief 主函數

4 * @param

5 * @retval

6 */

7 int main(void)

8 {

9

10 LED_GPIO_Config();

11

12 /*初始化USART1*/

13 Debug_USART_Config();

14

15 /* 初始化按鍵為中斷模式,按下中斷后會進入中斷服務函數 */

16 EXTI_Key_Config();

17

18 printf("\r\n歡迎使用秉火 STM32 F429 開發板。\r\n");

19 printf("\r\n秉火F429 睡眠模式例程\r\n");

20

21 printf("\r\n實驗說明:\r\n");

22

23 printf("\r\n 1.本程序中,綠燈表示STM32正常運行,紅燈表示睡眠狀態,藍燈表示剛從睡眠狀態被喚醒\r\n");

24 printf("\r\n 2.程序運行一段時間后自動進入睡眠狀態,在睡眠狀態下,可使用KEY1KEY2喚醒\r\n");

25 printf("\r\n 3.本實驗執行這樣一個循環:\r\n");

26printf("\r\n --》亮綠燈(正常運行)->亮紅燈(睡眠模式)->KEY1KEY2喚醒->亮藍燈(剛被喚醒)--\r\n");

27 printf("\r\n 4.在睡眠狀態下,DAP下載器無法給STM32下載程序,\r\n");

28 printf("\r\n可按KEY1KEY2喚醒后下載,\r\n");

29 printf("\r\n或按復位鍵使芯片處於復位狀態,然后在電腦上點擊下載按鈕,再釋放復位按鍵,即可下載\r\n");

30

31 while (1) {

32 /*********執行任務***************************/

33 printf("\r\n STM32正常運行,亮綠燈\r\n");

34

35 LED_GREEN;

36 Delay(0x3FFFFFF);

37

38 /*****任務執行完畢,進入睡眠降低功耗***********/

39

40

41 printf("\r\n進入睡眠模式,按KEY1KEY2按鍵可喚醒\r\n");

42

43 //使用紅燈指示,進入睡眠狀態

44 LED_RED;

45 //進入睡眠模式

46 __WFI(); //WFI指令進入睡眠

47

48 //等待中斷喚醒 K1K2按鍵中斷

49

50 /***被喚醒,亮藍燈指示***/

51 LED_BLUE;

52 Delay(0x1FFFFFF);

53

54 printf("\r\n已退出睡眠模式\r\n");

55 //繼續執行while循環

56 }

57 }

這個main函數的執行流程見圖 425    

425 睡眠模式實驗流程圖

(1)    程序中首先初始化了LED燈及串口以便用於指示芯片的運行狀態,並且把實驗板上的兩個按鍵都初始化成了中斷模式,以便當系統進入睡眠模式的時候可以通過按鍵來喚醒。這些硬件的初始化過程都跟前面章節中的一模一樣。

(2)    初始化完成后使用LED及串口表示運行狀態,在本實驗中,LED彩燈為綠色時表示正常運行,紅燈時表示睡眠狀態,藍燈時表示剛從睡眠狀態中被喚醒。

(3)    程序執行一段時間后,直接使用WFI指令進入睡眠模式,由於WFI睡眠模式可以使用任意中斷喚醒,所以我們可以使用按鍵中斷喚醒。

(4)    當系統進入停止狀態后,我們按下實驗板上的KEY1KEY2按鍵,即可使系統回到正常運行的狀態,當執行完中斷服務函數后,會繼續執行WFI指令后的代碼。

中斷服務函數

系統剛被喚醒時會進入中斷服務函數,見代碼清單 243

代碼清單 426 按鍵中斷的服務函數(stm32f4xx_it.c文件)

1

2 void KEY1_IRQHandler(void)

3 {

4 //確保是否產生了EXTI Line中斷

5 if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {

6 LED_BLUE;

7 printf("\r\n KEY1 按鍵中斷喚醒 \r\n");

8 EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);

9 }

10 }

11

12 void KEY2_IRQHandler(void)

13 {

14 //確保是否產生了EXTI Line中斷

15 if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {

16 LED_BLUE;

17 printf("\r\n KEY2 按鍵中斷喚醒 \r\n");

18 //清除中斷標志位

19 EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);

20 }

21 }

用於喚醒睡眠模式的中斷,其中斷服務函數也沒有特殊要求,跟普通的應用一樣。

42.3.3 下載驗證

下載這個實驗測試時,可連接上串口,在電腦端的串口調試助手獲知調試信息。當系統進入睡眠狀態的時候,可以按KEY1KEY2按鍵喚醒系統。

注意:

當系統處於睡眠模式低功耗狀態時(包括后面講解的停止模式及待機模式),使用DAP下載器是無法給芯片下載程序的,所以下載程序時要先把系統喚醒。或者使用如下方法:按着板子的復位按鍵,使系統處於復位狀態,然后點擊電腦端的下載按鈕下載程序,這時再釋放復位按鍵,就能正常給板子下載程序了。

42.4 PWR—停止模式實驗

在睡眠模式實驗的基礎上,我們進一步講解如何進入停止模式及喚醒后的狀態恢復。

42.4.1 硬件設計

本實驗中的硬件與睡眠模式中的一致,主要使用到了按鍵、LED彩燈以及使用串口輸出調試信息。

42.4.2 軟件設計

本小節講解的是"PWR—停止模式"實驗,請打開配套的代碼工程閱讀理解。

1.    程序設計要點

(1)    初始化用於喚醒的中斷按鍵;

(2)    設置停止狀態時的FLASH供電或掉電;

(3)    選擇電壓調節器的工作模式並進入停止狀態;

(4)    使用按鍵中斷喚醒芯片;

(5)    重啟HSE時鍾,使系統完全恢復停止前的狀態。

2.    代碼分析
重啟HSE時鍾

與睡眠模式不一樣,系統從停止模式被喚醒時,是使用HSI作為系統時鍾的,在STM32F429中,HSI時鍾一般為16MHz,與我們常用的180MHz相關太遠,它會影響各種外設的工作頻率。所以在系統從停止模式喚醒后,若希望各種外設恢復正常的工作狀態,就要恢復停止模式前使用的系統時鍾,本實驗中定義了一個SYSCLKConfig_STOP函數,用於恢復系統時鍾,它的定義見代碼清單 243

代碼清單 427 恢復系統時鍾(main.c文件)

1 /**

2 * @brief 停機喚醒后配置系統時鍾: 使能 HSE, PLL

3 * 並且選擇PLL作為系統時鍾.

4 * @param None

5 * @retval None

6 */

7 static void SYSCLKConfig_STOP(void)

8 {

9 /* After wake-up from STOP reconfigure the system clock */

10 /* 使能 HSE */

11 RCC_HSEConfig(RCC_HSE_ON);

12

13 /* 等待 HSE 准備就緒 */

14 while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

15

16 /* 使能 PLL */

17 RCC_PLLCmd(ENABLE);

18

19 /* 等待 PLL 准備就緒 */

20 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

21

22 /* 選擇PLL作為系統時鍾源 */

23 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

24

25 /* 等待PLL被選擇為系統時鍾源 */

26 while (RCC_GetSYSCLKSource() != 0x08);

27 }

這個函數主要是調用了各種RCC相關的庫函數,開啟了HSE時鍾、使能PLL並且選擇PLL作為時鍾源,從而恢復停止前的時鍾狀態。

main函數

停止模式實驗的main函數流程與睡眠模式的類似,主要是調用指令方式的不同及喚醒后增加了恢復時鍾的操作,見代碼清單 242

代碼清單 428 停止模式的main函數(main.c文件)

1

2 /**

3 * @brief 主函數

4 * @param

5 * @retval

6 */

7 int main(void)

8 {

9 LED_GPIO_Config();

10

11 /*初始化USART1*/

12 Debug_USART_Config();

13

14 /* 初始化按鍵為中斷模式,按下中斷后會進入中斷服務函數 */

15 EXTI_Key_Config();

16

17 printf("\r\n歡迎使用秉火 STM32 F429 開發板。\r\n");

18 printf("\r\n秉火F429 停止模式例程\r\n");

19

20 printf("\r\n實驗說明:\r\n");

21

22 printf("\r\n 1.本程序中,綠燈表示STM32正常運行,紅燈表示停止狀態,藍燈表示剛從停止狀態被喚醒\r\n");

23 printf("\r\n 2.程序運行一段時間后自動進入停止狀態,在停止狀態下,可使用KEY1KEY2喚醒\r\n");

24 printf("\r\n 3.本實驗執行這樣一個循環:\r\n");

25printf("\r\n --》亮綠燈(正常運行)->亮紅燈(停止模式)->KEY1KEY2喚醒->亮藍燈(剛被喚醒)---\r\n");

26 printf("\r\n 4.在停止狀態下,DAP下載器無法給STM32下載程序,\r\n");

27 printf("\r\n可按KEY1KEY2喚醒后下載,\r\n");

28 printf("\r\n或按復位鍵使芯片處於復位狀態,然后在電腦上點擊下載按鈕,再釋放復位按鍵,即可下載\r\n");

29

30 while (1) {

31 /*********執行任務***************************/

32 printf("\r\n STM32正常運行,亮綠燈\r\n");

33

34 LED_GREEN;

35 Delay(0x3FFFFFF);

36

37 /*****任務執行完畢,進入停止降低功耗***********/

38

39 printf("\r\n進入停止模式,按KEY1KEY2按鍵可喚醒\r\n");

40

41 //使用紅燈指示,進入停止狀態

42 LED_RED;

43

44 /*設置停止模式時,FLASH進入掉電狀態*/

45 PWR_FlashPowerDownCmd (ENABLE);

46 /* 進入停止模式,設置電壓調節器為低功耗模式,等待中斷喚醒 */

47 PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);

48

49 //等待中斷喚醒 K1K2按鍵中斷

50 /*********************被喚醒***********************/

51 //獲取剛被喚醒時的時鍾狀態

52 //時鍾源

53 clock_source_wakeup = RCC_GetSYSCLKSource ();

54 //時鍾頻率

55 RCC_GetClocksFreq(&clock_status_wakeup);

56

57 //從停止模式下被喚醒后使用的是HSI時鍾,此處重啟HSE時鍾,使用PLLCLK

58 SYSCLKConfig_STOP();

59

60 //獲取重新配置后的時鍾狀態

61 //時鍾源

62 clock_source_config = RCC_GetSYSCLKSource ();

63 //時鍾頻率

64 RCC_GetClocksFreq(&clock_status_config);

65

66 //因為剛喚醒的時候使用的是HSI時鍾,會影響串口波特率,輸出不對,所以在重新配置時鍾源后才使用串口輸出。

67 printf("\r\n重新配置后的時鍾狀態:\r\n");

68 printf(" SYSCLK頻率:%d,\r\n HCLK頻率:%d,\r\n PCLK1頻率:%d,\r\n PCLK2頻率:%d,\r\n時鍾源:%d (0表示HSI8表示PLLCLK)\n",

69 clock_status_config.SYSCLK_Frequency,

70 clock_status_config.HCLK_Frequency,

71 clock_status_config.PCLK1_Frequency,

72 clock_status_config.PCLK2_Frequency,

73 clock_source_config);

74

75 printf("\r\n剛喚醒的時鍾狀態:\r\n");

76 printf(" SYSCLK頻率:%d,\r\n HCLK頻率:%d,\r\n PCLK1頻率:%d,\r\n PCLK2頻率:%d,\r\n時鍾源:%d (0表示HSI8表示PLLCLK)\n",

77 clock_status_wakeup.SYSCLK_Frequency,

78 clock_status_wakeup.HCLK_Frequency,

79 clock_status_wakeup.PCLK1_Frequency,

80 clock_status_wakeup.PCLK2_Frequency,

81 clock_source_wakeup);

82

83 /*指示燈*/

84 LED_BLUE;

85 Delay(0x1FFFFFF);

86

87 printf("\r\n已退出停止模式\r\n");

88 //繼續執行while循環

89 }

90 }

這個main函數的執行流程見圖 425    

426 停止模式實驗流程圖

(1)    程序中首先初始化了LED燈及串口以便用於指示芯片的運行狀態,並且把實驗板上的兩個按鍵都初始化成了中斷模式,以便當系統進入停止模式的時候可以通過按鍵來喚醒。這些硬件的初始化過程都跟前面章節中的一模一樣。

(2)    初始化完成后使用LED及串口表示運行狀態,在本實驗中,LED彩燈為綠色時表示正常運行,紅燈時表示停止狀態,藍燈時表示剛從停止狀態中被喚醒。在停止模式下,I/O口會保持停止前的狀態,所以LED彩燈在停止模式時也會保持亮紅燈。

(3)    程序執行一段時間后,我們先用庫函數PWR_FlashPowerDownCmd設置FLASH的在停止狀態時使用掉電模式,接着調用庫函數PWR_EnterSTOPMode把調壓器設置在低功耗模式,並使用WFI指令進入停止狀態。由於WFI停止模式可以使用任意EXTI的中斷喚醒,所以我們可以使用按鍵中斷喚醒。

(4)    當系統進入睡眠狀態后,我們按下實驗板上的KEY1KEY2按鍵,即可喚醒系統,當執行完中斷服務函數后,會繼續執行WFI指令(PWR_EnterSTOPMode函數)后的代碼。

(5)    為了更清晰地展示停止模式的影響,在剛喚醒后,我們調用了庫函數RCC_GetSYSCLKSource以及RCC_GetClocksFreq獲取剛喚醒后的系統的時鍾源以及時鍾頻率,在使用SYSCLKConfig_STOP恢復時鍾后,我們再次獲取這些時狀態,最后再通過串口打印出來。

(6)    通過串口調試信息我們會知道剛喚醒時系統時鍾使用的是HIS時鍾,頻率為16MHz,恢復后的系統時鍾采用HSE倍頻后的PLL時鍾,時鍾頻率為180MHz

42.4.3 下載驗證

下載這個實驗測試時,可連接上串口,在電腦端的串口調試助手獲知調試信息。當系統進入停止狀態的時候,可以按KEY1KEY2按鍵喚醒系統。

注意:

當系統處於停止模式低功耗狀態時(包括睡眠模式及待機模式),使用DAP下載器是無法給芯片下載程序的,所以下載程序時要先把系統喚醒。或者使用如下方法:按着板子的復位按鍵,使系統處於復位狀態,然后點擊電腦端的下載按鈕下載程序,這時再釋放復位按鍵,就能正常給板子下載程序了。

42.5 PWR—待機模式實驗

最后我們來學習最低功耗的待機模式。

42.5.1 硬件設計

本實驗中的硬件與睡眠模式、停止模式中的一致,主要使用到了按鍵、LED彩燈以及使用串口輸出調試信息。要強調的是,由於WKUP引腳(PA0)必須使用上升沿才能喚醒待機狀態的系統,所以我們硬件設計的PA0引腳連接到按鍵KEY1,且按下按鍵的時候會在PA0引腳產生上升沿,從而可實現喚醒的功能,按鍵的具體電路請查看配套的原理圖。

42.5.2 軟件設計

本小節講解的是"PWR—待機模式"實驗,請打開配套的代碼工程閱讀理解。

1.    程序設計要點

(1)    清除WUF標志位;

(2)    使能WKUP喚醒功能;

(3)    進入待機狀態。

2.    代碼分析
main函數

待機模式實驗的執行流程比較簡單,見代碼清單 242

代碼清單 429 停止模式的main函數(main.c文件)

1

2 /**

3 * @brief 主函數

4 * @param

5 * @retval

6 */

7 int main(void)

8 {

9 LED_GPIO_Config();

10

11 /*初始化USART1*/

12 Debug_USART_Config();

13

14 /*初始化按鍵,不需要中斷,僅初始化KEY2即可,只用於喚醒的PA0引腳不需要這樣初始化*/

15 Key_GPIO_Config();

16

17 printf("\r\n歡迎使用秉火 STM32 F429 開發板。\r\n");

18 printf("\r\n秉火F429 待機模式例程\r\n");

19

20 printf("\r\n實驗說明:\r\n");

21

22 printf("1.綠燈表示本次復位是上電或引腳復位,紅燈表示即將進入待機狀態,藍燈表示本次是待機喚醒的復位\r\n");

23 printf("\r\n 2.長按KEY2按鍵后,會進入待機模式\r\n");

24 printf("\r\n 3.在待機模式下,按KEY1按鍵可喚醒,喚醒后系統會進行復位,程序從頭開始執行\r\n");

25 printf("\r\n 4.可通過檢測WU標志位確定復位來源\r\n");

26

27 printf("\r\n 5.在待機狀態下,DAP下載器無法給STM32下載程序,需要喚醒后才能下載");

28

29 //檢測復位來源

30 if (PWR_GetFlagStatus(PWR_FLAG_WU) == SET) {

31 LED_BLUE;

32 printf("\r\n待機喚醒復位 \r\n");

33 } else {

34 LED_GREEN;

35 printf("\r\n非待機喚醒復位 \r\n");

36 }

37 while (1) {

38 // K2 按鍵長按進入待機模式

39 if (KEY2_LongPress()) {

40

41     printf("\r\n即將進入待機模式,進入待機模式后可按KEY1喚醒,喚醒后會進行復位,程序從頭開始執行\r\n");

42 LED_RED;

43 Delay(0xFFFFFF);

44 /*清除WU狀態位*/

45 PWR_ClearFlag (PWR_FLAG_WU);

46

47 /* 使能WKUP引腳的喚醒功能,使能PA0*/

48 PWR_WakeUpPinCmd (ENABLE);

49

50 /* 進入待機模式 */

51 PWR_EnterSTANDBYMode();

52 }

53 }

54 }

這個main函數的執行流程見圖 425    

427 待機模式實驗流程圖

(1)    程序中首先初始化了LED燈及串口以便用於指示芯片的運行狀態,由於待機模式喚醒使用WKUP引腳並不需要特別的引腳初始化,所以我們調用的按鍵初始化函數Key_GPIO_Config它的內部只初始化了KEY2按鍵,而且是普通的輸入模式,對喚醒用的PA0引腳可以不初始化。當然,如果不初始化PA0的話,在正常運行模式中KEY1按鍵是不能正常運行的,我們這里只是強調待機模式的WKUP喚醒不需要中斷,也不需要像按鍵那樣初始化。本工程中使用的Key_GPIO_Config函數定義如代碼清單 4210所示。

代碼清單 4210 Key_GPIO_Config函數(bsp_key.c文件)

1

2 /**

3 * @brief 配置按鍵用到的I/O

4 * @param

5 * @retval

6 */

7 void Key_GPIO_Config(void)

8 {

9 GPIO_InitTypeDef GPIO_InitStructure;

10

11 /*開啟按鍵GPIO口的時鍾*/

12 RCC_AHB1PeriphClockCmd(KEY2_GPIO_CLK,ENABLE);

13

14 /*設置引腳為輸入模式*/

15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

16

17 /*設置引腳不上拉也不下拉*/

18 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

19

20 /*選擇按鍵的引腳*/

21 GPIO_InitStructure.GPIO_Pin = KEY2_PIN;

22

23 /*使用上面的結構體初始化按鍵*/

24 GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

25 }

(2)    使用庫函數PWR_GetFlagStatus檢測PWR_FLAG_WU標志位,當這個標志位為SET狀態的時候,表示本次系統是從待機模式喚醒的復位,否則可能是上電復位。我們利用這個區分兩種復位形式,分別使用藍色LED燈或綠色LED燈來指示。

(3)    while循環中,使用自定義的函數KEY2_LongPress來檢測KEY2按鍵是否被長時間按下,若長時間按下則進入待機模式,否則繼續while循環。KEY2_LongPress函數不是本章分析的重點,感興趣的讀者請自行查閱工程中的代碼。

(4)    檢測到KEY2按鍵被長時間按下,要進入待機模式。在使用庫函數PWR_EnterSTANDBYMode發送待機命令前,要先使用庫函數PWR_ClearFlag清除PWR_FLAG_WU標志位,並且使用庫函數PWR_WakeUpPinCmd使能WKUP喚醒功能,這樣進入待機模式后才能使用WKUP喚醒。

(5)    在進入待機模式前我們控制了LED彩燈為紅色,但在待機狀態時,由於I/O口會處於高阻態,所以LED燈會熄滅。

(6)    按下KEY1按鍵,會使PA0引腳產生一個上升沿,從而喚醒系統。

(7)    系統喚醒后會進行復位,從頭開始執行上述過程,與第一次上電時不同的是,這樣的復位會使PWR_FLAG_WU標志位改為SET狀態,所以這個時候LED彩燈會亮藍色。

42.5.3 下載驗證

下載這個實驗測試時,可連接上串口,在電腦端的串口調試助手獲知調試信息。長按實驗板上的KEY2按鍵,系統會進入待機模式,按KEY1按鍵可喚醒系統。

注意:

當系統處於待機模式低功耗狀態時(包括睡眠模式及停止模式),使用DAP下載器是無法給芯片下載程序的,所以下載程序時要先把系統喚醒。或者使用如下方法:按着板子的復位按鍵,使系統處於復位狀態,然后點擊電腦端的下載按鈕下載程序,這時再釋放復位按鍵,就能正常給板子下載程序了。

42.6 PWR—PVD電源監控實驗

這一小節我們學習如何使用PVD監控供電電源,增強系統的魯棒性。

42.6.1 硬件設計

本實驗中使用PVD監控STM32芯片的VDD引腳,當監測到供電電壓低於閾值時會產生PVD中斷,系統進入中斷服務函數進入緊急處理過程。所以進行這個實驗時需要使用一個可調的電壓源給實驗板供電,改變給STM32芯片的供電電壓,為此我們需要先了解實驗板的電源供電系統,見圖 428

428 實驗板的電源供電系統

    整個電源供電系統主要分為以下五部分:

(1)    6-12V的DC電源供電系統,這部分使用DC電源接口引入6-12V的電源,經過RT7272進行電壓轉換成5V電源,再與第二部分的"5V_USB"電源線連接在一起。

(2)    第二部分使用USB接口,使用USB線從外部引入5V電源,引入的電源經過電源開關及保險絲連接到"5V"電源線。

(3)    第三部分的是電源開關及保險絲,即當我們的實驗板使用DC電源或"5V_USB"線供電時,可用電源開關控制通斷,保險絲也會起保護作用。

(4)    "5V"電源線遍布整個板子,板子上各個位置引出的標有"5V"絲印的排針都與這個電源線直接相連。5V電源線給板子上的某些工作電壓為5V的芯片供電。5V電源還經過LDO穩壓芯片,輸出3.3V電源連接到"3.3V"電源線。

(5)    同樣地,"3.3V"電源線也遍布整個板子,各個引出的標有"3.3V"絲印的排針都與它直接相連,3.3V電源給工作電壓為3.3V的各種芯片供電。STM32芯片的VDD引腳就是直接與這個3.3V電源相連的,所以通過STM32的PVD監控的就是這個"3.3V"電源線的電壓。

當我們進行這個PVD實驗時,為方便改變"3.3V"電源線的電壓,我們可以把可調電源通過實驗板上引出的"5V"及"GND"排針給實驗板供電,當可調電源電壓降低時,LDO在"3.3V"電源線的供電電壓會隨之降低,即STM32PVD監控的VDD引腳電壓會降低,這樣我們就可以模擬VDD電壓下降的實驗條件,對PVD進行測試了。不過,由於這樣供電不經過保險絲,所以在調節電壓的時候要小心,不要給它供電遠高於5V,否則可能會燒壞實驗板上的芯片。

42.6.2 軟件設計

本小節講解的是"PWR—睡眠模式"實驗,請打開配套的代碼工程閱讀理解。為了方便把這個工程的PVD監控功能移植到其它應用,我們把PVD電壓監控相關的主要代碼編都寫到"bsp_pvd.c"及"bsp_pvd.h"文件中,這些文件是我們自己編寫的,不屬於標准庫的內容,可根據您的喜好命名文件。

1.    程序設計要點

(1)    初始化PVD中斷;

(2)    設置PVD電壓監控等級並使能PVD;

(3)    編寫PVD中斷服務函數,處理緊急任務。

2.    代碼分析
初始化PVD

使用PVD功能前需要先初始化,我們把這部分代碼封裝到PVD_Config函數中,見代碼清單 4211

代碼清單 4211 初始化PVD(bsp_pvd.c文件)

1

2 /**

3 * @brief 配置PVD.

4 * @param None

5 * @retval None

6 */

7 void PVD_Config(void)

8 {

9 NVIC_InitTypeDef NVIC_InitStructure;

10 EXTI_InitTypeDef EXTI_InitStructure;

11

12 /*使能 PWR 時鍾 */

13 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

14

15 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

16

17 /* 使能 PVD 中斷 */

18 NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;

19 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

20 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

21 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

22 NVIC_Init(&NVIC_InitStructure);

23

24 /* 配置 EXTI16(PVD 輸出) 來產生上升下降沿中斷*/

25 EXTI_ClearITPendingBit(EXTI_Line16);

26 EXTI_InitStructure.EXTI_Line = EXTI_Line16;

27 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

28 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

29 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

30 EXTI_Init(&EXTI_InitStructure);

31

32 //配置PVD級別5

33 // (PVD檢測電壓的閾值為2.8VVDD電壓低於2.8V時產生PVD中斷,

34 //具體數據可查詢數據手冊獲知)

35 /*具體級別根據自己的實際應用要求配置*/

36 PWR_PVDLevelConfig(PWR_PVDLevel_5);

37

38 /* 使能PVD輸出 */

39 PWR_PVDCmd(ENABLE);

40 }

在這段代碼中,執行的流程如下:

(1)    配置PVD的中斷優先級。由於電壓下降是非常危急的狀態,所以請盡量把它配置成最高優先級。

(2)    配置了EXTI16線的中斷源,設置EXTI16是因為PVD中斷是通過EXTI16產生中斷的(GPIO的中斷是EXTI0-EXTI15)

(3)    使用庫函數PWR_PVDLevelConfig設置PVD監控的電壓閾值等級,各個閾值等級表示的電壓值請查閱表 422STM32的數據手冊。

(4)    最后使用庫函數PWR_PVDCmd使能PVD功能。

PVD中斷服務函數

配置完成PVD后,還需要編寫中斷服務函數,在其中處理緊急任務,本工程的PVD中斷服務函數見代碼清單 4212

代碼清單 4212 PVD中斷服務函數(stm32f4xx_it.c文件)

1

2 /**

3 * @brief PVD中斷請求

4 * @param None

5 * @retval None

6 */

7 void PVD_IRQHandler(void)

8 {

9 /*檢測是否產生了PVD警告信號*/

10 if (PWR_GetFlagStatus (PWR_FLAG_PVDO)==SET) {

11 /* 亮紅燈,實際應用中應進入緊急狀態處理 */

12 LED_RED;

13

14 }

15 /* 清除中斷信號*/

16 EXTI_ClearITPendingBit(EXTI_Line16);

17

18 }

19

注意這個中斷服務函數的名是PVD_IRQHandler而不是EXTI16_IRQHandler(STM32沒有這樣的中斷函數名),示例中我們僅點亮了LED紅燈,不同的應用中要根據需求進行相應的緊急處理。

main函數

本電源監控實驗的main函數執行流程比較簡單,僅調用了PVD_Config配置監控功能,當VDD供電電壓正常時,板子亮綠燈,當電壓低於閾值時,會跳轉到中斷服務函數中,板子亮紅燈,見代碼清單 242

代碼清單 4213 停止模式的main函數(main.c文件)

1 /**

2 * @brief 主函數

3 * @param

4 * @retval

5 */

6 int main(void)

7 {

8 LED_GPIO_Config();

9

10 //亮綠燈,表示正常運行

11 LED_GREEN;

12

13 //配置PVD,當電壓過低時,會進入中斷服務函數,亮紅燈

14 PVD_Config();

15

16 while (1) {

17

18 /*正常運行的程序*/

19

20 }

21

22 }

23

24

42.6.3 下載驗證

本工程的驗證步驟如下:

(1)    通過電腦把本工程編譯並下載到實驗板;

(2)    把下載器、USBDC電源等外部供電設備都拔掉;

(3)    按"硬件設計"小節中的說明,使用可調電源通過"5V"及"GND"排針給實驗板供5V電源;(注意要先調好可調電源的電壓再連接,防止燒壞實驗板)

(4)    復位實驗板,確認板子亮綠燈,表示正常狀態;

(5)    持續降低可調電源的輸出電壓,直到實驗板亮紅燈,這時表示PVD檢測到電壓低於閾值。

 

本工程中,我們實測PVD閾值等級為"PWR_PVDLevel_5"時,當可調電源電壓降至4.4V時,板子亮紅燈,此時的"3.3V"電源引腳的實測電壓為2.75V;PVD閾值等級為"PWR_PVDLevel_3"時,當可調電源電壓降至4.2V時,板子亮紅燈,此時的"3.3V"電源引腳的實測電壓為2.55V;

注意:

由於這樣使用可調電源供電不經過保險絲,所以在調節電壓的時候要小心,不要給它供電遠高於5V,否則可能會燒壞實驗板上的芯片。

42.7 每課一問

10.    在睡眠模式實驗的基礎上編寫程序,添加SYSTICK定時器,使用它控制LED燈1秒翻轉狀態1次,控制完畢后立即重新進入睡眠狀態。

11.    在停止模式實驗的基礎上改寫程序,嘗試在系統喚醒后(緊接着PWR_EnterSTOPMode函數之后)立即使用串口打印調試信息到電腦端,觀察實驗現象並解釋。

答:由於系統時鍾沒有恢復,導致串口波特率與原配置不符,導致通訊錯誤。

12.    在PVD電源監控實驗的基礎上,修改PVD監控的電壓閾值等級,進入PVD中斷時"3.3V"電源線的臨界電壓。

 


免責聲明!

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



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