1、前言
近日,在學習APM32開發板關于PMU模塊的內容,看到很多內容都是調用WFI內核指令進入低功耗模式,于是自己想嘗試調用WFE內核指令進入低功耗模式,但在APM32F10xx中,我運用按鍵中斷,在中斷調用PMU_EnterSTOPMode庫函數,用WFE內核指令進入STOP模式是存在問題的,后經查驗解決了問題,于是在此進行了內容記錄。
2、相關知識介紹
2.1、低功耗模式概述
當APM32在系統或者電源復位后,芯片處于運行狀態,此時HCLK為CPU提供時鐘,內核執行程序代碼,當CPU不需要運行時,可以采用低功耗模式來降低芯片運行的電流。
2.2、低功耗模式
低功耗模式可分為睡眠模式和深度睡眠模式,其中深度睡眠模式分別停止模式和待機模式。而本文的重點則在于講解進入停止模式。
2.3、進入停止模式配置
如上,進入停止模式需要將SCB->SCR->SLEEPDEEP置為1,同時PMU->CTRL->PDDSCFG置為0,同時要執行WFI/WFE指令進入停止模式。其中,兩個內核指令的區別如下:
如上,當調用WFI內核指令時,會直接進入睡眠/深度睡眠模式。當調用WFE指令時,會根據事件鎖存器的值來判斷能否直接進入睡眠/深度睡眠模式。如下,我做了一個流程圖:
3、問題分析及解決
3.1、配置的關鍵代碼
int main(void)
{
RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR));
APM_MINI_LEDInit(LED2);
APM_MINI_LEDInit(LED3);
/* KEY1 KEY2 Set */
//APM_MINI_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
APM_MINI_PBInit(BUTTON_KEY1,BUTTON_MODE_EINT);
APM_MINI_PBInit(BUTTON_KEY2,BUTTON_MODE_EINT);
/* NVIC Priority Set */
NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_1);
NVIC_EnableIRQRequest(EINT0_IRQn, 0, 1);
NVIC_EnableIRQRequest(EINT1_IRQn, 1, 1);
APM_MINI_LEDOn(LED2);
APM_MINI_LEDOff(LED3);
/* Enable PMU Periph Clock */
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
PMU_Reset();
while (1)
{
Delay(0x7FFFFF);
APM_MINI_LEDToggle(LED2);
}
}
voidEint1_Isr(void)
{
if (EINT_ReadIntFlag(KEY1_BUTTON_EINT_LINE)!= RESET)
{
APM_MINI_LEDOn(LED3);
APM_MINI_LEDOff(LED2);
/* Enter STOP Mode */
PMU_EnterSTOPMode(PMU_REGULATOR_LOWPOWER, PMU_STOP_ENTRY_WFE);
EINT_ClearIntFlag(KEY1_BUTTON_EINT_LINE);
}
}
voidEint0_Isr(void)
{
if (EINT_ReadIntFlag(KEY2_BUTTON_EINT_LINE)!= RESET)
{
SystemInit();
APM_MINI_LEDOff(LED3);
/* Wait for system init */
Delay(0xfffff);
EINT_ClearIntFlag(KEY2_BUTTON_EINT_LINE);
}
}
如上代碼,按下按鍵1后會進入睡眠模式,LED2燈滅,LED3常亮。按下按鍵2后會從睡眠模式中喚醒,LED2跳燈,LED3燈滅。但真實的現象便是按下按鍵1后,LED2仍處于跳燈狀態,但LED3常亮,因此我初步判斷第一次運用WFE指令時沒有進入停止模式,但我從而驗證我的判斷?
3.2、PMU_EnterSTOPMode函數
voidPMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry)
{
/* Clear PDDSCFG and LPDSCFG bits */
PMU->CTRL_B.PDDSCFG = 0x00;
PMU->CTRL_B.LPDSCFG = 0x00;
/* Set LPDSCFG bit according to regulatorvalue */
PMU->CTRL_B.LPDSCFG = regulator;
/* Set Cortex System Control Register */
SCB->SCR |= (uint32_t)0x04;
/* Select STOP mode entry*/
if (entry == PMU_STOP_ENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex SystemControl Register */
SCB->SCR &=(uint32_t)~((uint32_t)0x04);
}
如下庫API函數中,運用一次WFE內核指令,當我第一次看到這個函數時,并沒有發現什么問題,于是,我照著手冊深入我的問題探究。于是,我在《Cortex M3與M4權威指南》中找到如下內容:
當我們運用WFE內核指令進入停止模式時,一般調用兩次WFE內核指令,因為事件寄存器會因為中斷事件的產生而置位。這時,在結合2.3中內容,我便知曉了問題的答案。因為在初始化的按鍵配置中,按鍵1和按鍵2連接了外部中斷線,當我調用該庫函數中,運用WFE指令進入停止模式時,第一次會因為有中斷事件的產生,WFE的作用是運用于清除事件鎖存器的值,而第二次才用于進入睡眠模式,因此在后面的Demo例程中,我給出了一種解決方法。
注:
在解決問題的過程中,我給出了第二種解決方法,便是不通過按鍵中斷調用WFE內核指令進入停止模式,而是在主函數中直接對按鍵進行一個是否按鍵的判斷,按下即進入睡眠模式。(這兩種方法均已通過實驗)。
本次分享到此結束,如有問題大家一起在評論區討論,謝謝
-
內核
+關注
關注
3文章
1376瀏覽量
40316 -
指令
+關注
關注
1文章
608瀏覽量
35752 -
開發板
+關注
關注
25文章
5080瀏覽量
97678 -
PMU
+關注
關注
1文章
108瀏覽量
21628
原文標題:APM32芯得 EP.32 | 基于APM32F103 Stop模式關于WFE內核命令問題分析及解決
文章出處:【微信號:geehysemi,微信公眾號:Geehy極海半導體】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論