1、前言
近日,在學(xué)習(xí)APM32開發(fā)板關(guān)于PMU模塊的內(nèi)容,看到很多內(nèi)容都是調(diào)用WFI內(nèi)核指令進(jìn)入低功耗模式,于是自己想嘗試調(diào)用WFE內(nèi)核指令進(jìn)入低功耗模式,但在APM32F10xx中,我運(yùn)用按鍵中斷,在中斷調(diào)用PMU_EnterSTOPMode庫(kù)函數(shù),用WFE內(nèi)核指令進(jìn)入STOP模式是存在問題的,后經(jīng)查驗(yàn)解決了問題,于是在此進(jìn)行了內(nèi)容記錄。
2、相關(guān)知識(shí)介紹
2.1、低功耗模式概述
當(dāng)APM32在系統(tǒng)或者電源復(fù)位后,芯片處于運(yùn)行狀態(tài),此時(shí)HCLK為CPU提供時(shí)鐘,內(nèi)核執(zhí)行程序代碼,當(dāng)CPU不需要運(yùn)行時(shí),可以采用低功耗模式來降低芯片運(yùn)行的電流。
2.2、低功耗模式
低功耗模式可分為睡眠模式和深度睡眠模式,其中深度睡眠模式分別停止模式和待機(jī)模式。而本文的重點(diǎn)則在于講解進(jìn)入停止模式。
2.3、進(jìn)入停止模式配置
如上,進(jìn)入停止模式需要將SCB->SCR->SLEEPDEEP置為1,同時(shí)PMU->CTRL->PDDSCFG置為0,同時(shí)要執(zhí)行WFI/WFE指令進(jìn)入停止模式。其中,兩個(gè)內(nèi)核指令的區(qū)別如下:
如上,當(dāng)調(diào)用WFI內(nèi)核指令時(shí),會(huì)直接進(jìn)入睡眠/深度睡眠模式。當(dāng)調(diào)用WFE指令時(shí),會(huì)根據(jù)事件鎖存器的值來判斷能否直接進(jìn)入睡眠/深度睡眠模式。如下,我做了一個(gè)流程圖:
3、問題分析及解決
3.1、配置的關(guān)鍵代碼
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后會(huì)進(jìn)入睡眠模式,LED2燈滅,LED3常亮。按下按鍵2后會(huì)從睡眠模式中喚醒,LED2跳燈,LED3燈滅。但真實(shí)的現(xiàn)象便是按下按鍵1后,LED2仍處于跳燈狀態(tài),但LED3常亮,因此我初步判斷第一次運(yùn)用WFE指令時(shí)沒有進(jìn)入停止模式,但我從而驗(yàn)證我的判斷?
3.2、PMU_EnterSTOPMode函數(shù)
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);
}
如下庫(kù)API函數(shù)中,運(yùn)用一次WFE內(nèi)核指令,當(dāng)我第一次看到這個(gè)函數(shù)時(shí),并沒有發(fā)現(xiàn)什么問題,于是,我照著手冊(cè)深入我的問題探究。于是,我在《Cortex M3與M4權(quán)威指南》中找到如下內(nèi)容:
當(dāng)我們運(yùn)用WFE內(nèi)核指令進(jìn)入停止模式時(shí),一般調(diào)用兩次WFE內(nèi)核指令,因?yàn)槭录?a href="http://ttokpm.com/tags/寄存器/" target="_blank">寄存器會(huì)因?yàn)橹袛嗍录漠a(chǎn)生而置位。這時(shí),在結(jié)合2.3中內(nèi)容,我便知曉了問題的答案。因?yàn)樵诔跏蓟陌存I配置中,按鍵1和按鍵2連接了外部中斷線,當(dāng)我調(diào)用該庫(kù)函數(shù)中,運(yùn)用WFE指令進(jìn)入停止模式時(shí),第一次會(huì)因?yàn)橛兄袛嗍录漠a(chǎn)生,WFE的作用是運(yùn)用于清除事件鎖存器的值,而第二次才用于進(jìn)入睡眠模式,因此在后面的Demo例程中,我給出了一種解決方法。
注:
在解決問題的過程中,我給出了第二種解決方法,便是不通過按鍵中斷調(diào)用WFE內(nèi)核指令進(jìn)入停止模式,而是在主函數(shù)中直接對(duì)按鍵進(jìn)行一個(gè)是否按鍵的判斷,按下即進(jìn)入睡眠模式。(這兩種方法均已通過實(shí)驗(yàn))。
本次分享到此結(jié)束,如有問題大家一起在評(píng)論區(qū)討論,謝謝
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1359瀏覽量
40183 -
指令
+關(guān)注
關(guān)注
1文章
606瀏覽量
35612 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
4888瀏覽量
97026 -
PMU
+關(guān)注
關(guān)注
1文章
107瀏覽量
21548
原文標(biāo)題:APM32芯得 EP.32 | 基于APM32F103 Stop模式關(guān)于WFE內(nèi)核命令問題分析及解決
文章出處:【微信號(hào):geehysemi,微信公眾號(hào):Geehy極海半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論