5.1 實驗內容
通過本實驗主要學習以下內容:
? PMU原理;
? 低功耗的進入以及退出操作;
5.2 實驗原理
5.2.1 PMU結構原理
PMU即電源管理單元,其內部結構下圖所示,由該圖可知,GD32H7XX系列MCU具有三個電源域,包括VDD/VDDA電源域、0.9V電源域以及電池備份域,其中,VDD /VDDA域由電源直接供電。0.9V由內部LDO或者外部Vcore供電。在備份域中有一個電源切換器,當VDD/VDDA電源關閉時,電源切換器可以將備份域的電源切換到VBAT引腳,此時備份域由VBAT引腳(電池)供電。
VDD / VDDA 域包括 VDD 域和 VDDA 域兩部分。 VDD 域包括 HXTAL(高速外部晶體振蕩器)、 POR/ PDR(上電 / 掉電復位)、 FWDGT(獨立看門狗定時器)和除 PC13、 PC14 和 PC15 之外的所有 PAD 等等。 VDDA 域包括 ADC / DAC(AD / DA 轉換器)、 LPIRC4M(內部 4MHz RC振蕩器)、 IRC64M(內部 64M RC 振蕩器)、 IRC32K(內部 32KHz RC 振蕩器) PLLs(鎖相環(huán))、 LVD(低電壓檢測器)、 VOVD(0.9V 電壓檢測器)、 VAVD(VDDA 電壓檢測器)、 TVD(溫度電壓檢測器)和 BVD(VBAK 電壓檢測器)等等。
POR / PDR(上電 / 掉電復位) 電路檢測 VDD / VDDA 并在電壓低于特定閾值時產生電源復位信號復位除備份域之外的整個芯片。下圖顯示了供電電壓和電源復位信號之間的關系。 VPOR 表示上電復位的閾值電壓, VPDR 表示掉電復位的閾值電壓。遲滯電壓 Vhyst 值約為 50mV。
BOR 電路檢測 VDD / VDDA 并在 BOR_TH 不為 0b11,同時電壓低于選項字節(jié)的 BOR_TH 定義的閾值時產生電源復位信號復位除備份域之外的整個芯片。 POR / PDR(上電 / 掉電復位)電路處于檢測狀態(tài),無論選項字節(jié)的 BOR_TH 是否為 0b11。 下圖顯示了供電電壓和 BOR 復位信號之間的關系。 VBOR 表示 BOR 復位的閾值電壓,該值在選項字節(jié) BOR_TH中定義。遲滯電壓 Vhyst 值為 100mV。
LVD 的功能是檢測 VDD / VDDA 供電電壓是否低于低電壓檢測閾值,該閾值由電源控制寄存器 0(PMU_CTL0)中的 LVDT[2:0]位進行配置。 LVD 通過 LVDEN 置位使能,位于電源控制狀態(tài)寄存器(PMU_CS)中的 LVDF 位表示低電壓事件是否出現(xiàn),該事件連接至 EXTI 的第 16 線,用戶可以通過配置 EXTI 的第 16 線產生相應的中斷。下圖顯示了 VDD / VDDA 供電電壓和 LVD 輸出信號的關系。(LVD 中斷信號依賴于 EXTI 第 16 線的上升或下降沿配置)。遲滯電壓 Vhyst 值為 100mV。
為提高 ADC 和 DAC 的精度,可將獨立的外部參考電壓連接至 ADC / DAC 引腳 VREF+ / VREF-。
VDDA模擬電壓檢測器(VAVD)用于檢測 VDDA電源電壓是否低于電源控制寄存器(PMU_CTL0)中 VAVDVC[1:0]位域選擇的編程閾值。通過置位 VAVDEN 位能夠使能 VAVD, PMU_CS 寄存器中的 VAVDF 位指示 VDDA 高于或低于指定的 VAVD 閾值,如果 VAVDF 置位能夠產生對應的事件,這個事件在內部連接到 EXTI 16。如果通過 EXTI 寄存器使能,可以產生一個中斷。
和備份域電壓閾值監(jiān)測類似,通過與溫度高、低兩個閾值水平比較可以來監(jiān)測結溫。PMU_CTL1寄存器中 TEMPH 和 TEMPL 標志指示設備溫度是否高于或低于閾值??梢酝ㄟ^ PMU_CTL1寄存器中的 VBTMEN 位使能 / 關閉溫度電壓閾值監(jiān)測。使能后,溫度閾值監(jiān)測將增加功耗。溫度閾值監(jiān)測可以用來觸發(fā)執(zhí)行溫度控制任務的相關的程序。只有 PMU_CTL1 寄存器中的VBTMEN 位置位,溫度閾值監(jiān)測才有效。
TEMPH 和 TEMPL 喚醒中斷可用于 RTC 觸發(fā)信號。
主要功能包括 Cortex?-M7 內核邏輯、 AHB / APB 外設、備份域和 VDD / VDDA 域的 APB 接口。當 0.9V 電壓上電后, POR 將在 0.9V 域中產生一個復位序列,復位完成后,如果要進入指定的省電模式,須先配置相關的控制位,之后一旦執(zhí)行 WFI 或 WFE 指令,設備便進入該省電模式。
使用 SMPS 降壓穩(wěn)壓器和 LDO,可以設置 0.9V 電源域的供電電源。不同配置可提供七種有效的 0.9V 電源域供電模式。
注意:基于供電穩(wěn)定性以及芯片散熱考慮,目前推薦采用模式6旁路模式進行供電。在旁路供電模式下內部SMPS和LDO是關閉狀態(tài),內部Vcore由Vcore引腳進行供電,Vcore引腳外接0.9V電源。如下圖所示。
電池備份域由內部電源切換器來選擇 VDD 供電或 VBAT(電池)供電,然后由 VBAK 為備份域供電,該備份域包含 RTC(實時時鐘)、 LXTAL(低速外部晶體振蕩器), BPOR(備份域上電復位)和 BREG,以及 PC13 至 PC15 共 3 個 BKP PAD。為了確保備份域中寄存器的內容及 RTC正常工作,當 VDD 關閉時, VBAT 引腳可以連接至電池或其他備份電源供電。電源切換器是由VDD / VDDA 域掉電復位電路控制的。對于沒有外部電池的應用,建議將 VBAT 引腳通過 100nF 的外部陶瓷去耦電容連接到 VDD 引腳上。
注意: 由于PC13至PC15引腳是通過電源切換器供電的,電源切換器僅可通過小電流,因此當PC13至PC15的GPIO口在輸出模式時,其工作的速度不能超過2MHz(最大負載為30Pf)。
若讀者有在VDD掉電情況下RTC繼續(xù)工作的應用需求,需要VBAT引腳外接電池并使用LXTAL外部低頻晶振,這樣在VDD掉電的情況下,VBAT供電將會由VDD切換到VBAT,LXTAL和RTC均可正常工作,后續(xù)VDD上電后同步RTC寄存器即可獲取正確的RTC時間。
5.2.2 低功耗模式
GD32H7xx系列MCU具有三種低功耗模式,分別為睡眠模式、深度睡眠模式和待機模式。
睡眠模式與 Cortex?-M7 的 SLEEPING 模式相對應。在睡眠模式下,僅關閉 Cortex?-M7 的時鐘。如需進入睡眠模式,只要清除 Cortex?-M7 系統(tǒng)控制寄存器中的 SLEEPDEEP 位,并執(zhí)行一條 WFI 或 WFE 指令即可。如果睡眠模式是通過執(zhí)行 WFI 指令進入的,任何中斷都可以喚醒系統(tǒng)。如果睡眠模式是通過執(zhí)行 WFE 指令進入的,任何喚醒事件都可以喚醒系統(tǒng)(如果SEVONPEND 為 1,任何中斷都可以喚醒系統(tǒng),請參考 Cortex?-M7 技術手冊)。由于無需在進入或退出中斷上消耗時間,該模式所需的喚醒時間最短。
深度睡眠模式與 Cortex?-M7 的 SLEEPDEEP 模式相對應。在深度睡眠模式下, 0.9V 域中的所有時鐘全部關閉, LPIRC4M、 IRC64M、 HXTAL 及 PLLs 也全部被禁用。進入深度睡眠模式之前,先將 Cortex?-M7 系統(tǒng)控制寄存器的 SLEEPDEEP 位置 1,再將 PMU_CTL0 寄存器的LPMOD 位配置為 0b1,然后執(zhí)行 WFI 或 WFE 指令即可進入深度睡眠模式。如果睡眠模式是通過執(zhí)行 WFI 指令進入的,任何來自 EXTI 的中斷可以將系統(tǒng)從深度睡眠模式中喚醒。如果睡眠模式是通過執(zhí)行 WFE 指令進入的,任何來自 EXTI 的事件可以將系統(tǒng)從深度睡眠模式中喚醒(如果 SEVONPEND 為 1,任何來自 EXTI 的中斷都可以喚醒系統(tǒng),請參考 Cortex?-M7 技術手冊)。
待機模式是基于 Cortex?-M7 的 SLEEPDEEP 模式實現(xiàn)的。在待機模式下,整個 0.9V 域全部停止供電, LDO 關閉,同時包括 LPIRC4M、 IRC64M、 HXTAL 和 PLLs 也會被關閉。進入待機模式前,先將 Cortex?-M7 系統(tǒng)控制寄存器的 SLEEPDEEP 位置 1,再將 PMU_CTL0 寄存器的 LPMOD 位域配置為 0b1,再清除 PMU_CS 寄存器的 WUF 位,然后執(zhí)行 WFI 或 WFE指令,系統(tǒng)進入待機模式, PMU_CS 寄存器的 STBF 位狀態(tài)表示 MCU 是否已進入待機模式。待機模式有四個喚醒源,包括來自 NRST 引腳的外部復位, RTC 鬧鐘, FWDGT 復位, WKUP引腳的上升沿。待機模式可以達到最低的功耗,但喚醒時間最長。另外,一旦進入待機模式,SRAM 和 0.9V 電源域寄存器的內容都會丟失。退出待機模式時,會發(fā)生上電復位,復位之后Cortex?-M7 將從 0x00000000 地址開始執(zhí)行指令代碼。
低功耗模式相關數據可參考下表,不同的低功耗模式是通過關閉不同時鐘以及電源來實現(xiàn)的,關閉的時鐘和電源越多,MCU所進入的睡眠模式將會越深,功耗也會越低,帶來的喚醒時間也會越長,其喚醒源也會越少。
各種睡眠模式下的功耗可以參考數據手冊描述,睡眠模式下相較于同主頻模式下的運行模式功耗減少約50%,深度睡眠和待機模式功耗更低,如下表所示,深度睡眠模式下功耗常溫典型值為2-3ma。
注意:由于深度睡眠模式具有較低的功耗,喚醒后繼續(xù)從斷點處執(zhí)行,因而具有更廣泛的應用場景,但需注意若需達到較一致的MCU深度睡眠功耗,需要將系統(tǒng)中未使用的MCU引腳均配置為模擬輸入狀態(tài),包括芯片內部未引出的pad。
Note:中間為典型數值。
5.3 硬件設計
本例程stanby的喚醒使用到了PA0喚醒引腳,其電路如下所示。
5.4 代碼解析
本例程實現(xiàn)deepsleep以及standby的進入以及喚醒測試,首先我們來看下主函數,如下所示。該主函數首先配置了驅動初始化、打印和LED函數,并打印Example of Low Power Test Demo。之后查詢是否進入過Standby模式,如果進入過Standby模式,表示當前狀態(tài)為standby喚醒后的復位,則打印A reset event from Standby mode has occurred,并翻轉LED2,因而驗證standby喚醒的時候,其現(xiàn)象可觀察到LED2的翻轉。之后使能wakeup引腳的喚醒以及USER按鍵的初始化,此時將wakeup KEY配置為中斷模式。在while(1)中,查詢USER KEY按下的時間,如果按下超過3S,則打印Entering Standby Mode.并進入standby模式,如果USER KEY按下不超過3S,則打印Enter Deepsleep mode.并進入Deepsleep模式,從deepsleep模式喚醒后需要重新配置時鐘,打印Exit Deepsleep mode.并翻轉LED1。Standby的喚醒使用PA0 wakeup引腳,deepsleep的喚醒可使用任何EXTI中斷,本實例中使用wakeup按鍵中斷喚醒。
C
int main(void)
{
rcu_periph_clock_enable(RCU_PMU);
driver_init();
//注冊按鍵掃描
driver_tick_handle[0].tick_value=10;
driver_tick_handle[0].tick_task_callback=key_scan_10ms_callhandle;
bsp_uart_init(&BOARD_UART); ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????/* 板載UART初始化 */
printf_log("Example of Low Power Test Demo.\r\n");
delay_ms(2000);
bsp_led_group_init();
/* 判斷是否進入過Stanby模式 */
if(pmu_flag_get(PMU_FLAG_STANDBY)==SET)
{
printf_log("A reset event from Standby mode has occurred.\r\n");
bsp_led_toggle(&LED2);
pmu_flag_clear(PMU_FLAG_STANDBY);
}
/* 配置PA0 Wakeup喚醒功能 */
pmu_wakeup_pin_enable(PMU_WAKEUP_PIN0);
WKUP_KEY.key_gpio->gpio_mode = INT_HIGH;
WKUP_KEY.key_gpio->int_callback = WKUP_KEY_IRQ_callback;
bsp_key_group_init();
nvic_irq_enable(EXTI0_IRQn,0,0);
while (1)
{
/* 檢測KEY1按鍵是否被按下,如果按下,進入standby模式 */
if(USER_KEY.press_timerms >= PRESS_3000MS)
{
USER_KEY.press_timerms=PRESS_NONE;
printf_log("Entering Standby Mode.\r\n");
bsp_led_toggle(&LED2);
pmu_to_standbymode();
}
/* 檢測KEY2按鍵是否被按下,如果按下,進入Deepsleep模式 */
if(USER_KEY.press_timerms >= PRESS_50MS)
{
USER_KEY.press_timerms=PRESS_NONE;
printf_log("Enter Deepsleep mode.\r\n");
bsp_led_toggle(&LED1);
bsp_lcd_backlight_off();
pmu_to_deepsleepmode(WFI_CMD);
bsp_lcd_backlight_on();
printf_log("Exit Deepsleep mode.\r\n");
bsp_led_toggle(&LED1);
}
}
}
5.5 實驗結果
將本實驗歷程燒錄到海棠派開發(fā)板中,按下user key按鍵超過3S,松開后MCU將進入standby模式,并打印Entering Standby Mode.,然后按下wakeup按鍵,將從stanby模式喚醒,打印A reset event from Standby mode has occurred.并翻轉LED2,之后短按USER KEY,將打印Enter Deepsleep mode.進入deepsleep模式,然后按下wakeup按鍵將從deepsleep模式下喚醒,喚醒后重新配置時鐘,打印Exit Deepsleep mode.并將LED1翻轉。