CW32系列芯片支持3種工作模式,運行模式、休眠模式以及深度休眠模式,本文以CW32L083為例介紹低功耗模式的特性。MCU上電以后,系統自動進入運行模式,可以通過軟件配置,進入休眠或者深度休眠兩種低功耗模式,進入低功耗運行狀態后,可以通過外設中斷觸發喚醒機制,使得系統返回到運行模式,三種工作模式的轉換機制如下圖所示:
運行模式下 CPU 正常運行,所有模塊用戶均可正常使用。
? 休眠模式(Sleep mode)
休眠模式下,CPU 停止運行,所有外設不受影響,所有I/O引腳保持狀態不變。
? 深度休眠模式(DeepSleep mode)
深度休眠模式下,CPU停止運行,高速時鐘(HSE、HSIOSC)自動關閉,低速時鐘(LSE、 LSI、RC10K、RC150K)保持原狀態不變。深度休眠模式的功耗遠小于休眠模式。
CW32L083可以使用等待中斷專用指令,WFI(Wait for Interrupt),配合系統控制寄存器(SCR, System Control Register)的SLEEPONEXIT和SLEEPDEEP位域,可實現立即進入或退出(中斷服務程序)時進入休眠模式或深度休眠模式。
? 立即進入
執行WFI指令,MCU將立即進入休眠模式(SLEEPDEEP為0時)或深度休眠模式(SLEEPDEEP為1時)
? 退出時進入
將SLEEPONEXIT位置1,當退出最低優先級的中斷服務程序后,MCU會進入休眠模式(SLEEPDEEP為0時)或深度休眠模式(SLEEPDEEP為 1時),而不需執行WFI指令 。
注:在深度休眠模式下,系統將自動關閉高速時鐘,如果需要在深度休眠模式下使部分外設仍保持運行,則需要在進入深度休眠模式前,啟動相應的低速時鐘并將該外設時鐘設置為此低速時鐘。
在休眠模式或深度休眠模式下,均可通過中斷來喚醒CPU,返回到運行模式。如果用戶在中斷服務程序中執行WFI命令進入休眠(包括深度休眠),則需要比此中斷更高優先級的中斷才能喚醒CPU,因此,強烈建議在準備進入休眠前,應先處理完所有中斷服務程序,并且清除所有中斷請求和中斷標志,以下是配置進入低功耗模式時所需注意的事項。
?建議在進入低功耗模式前加一段時間的延遲,以免出現上電就進入低功耗模式,無法燒錄程序。
?系統可以配置從Deepsleep喚醒后,系統時鐘來源是HSI還是進入休眠前的時鐘。
?系統進入低功耗模式,端口狀態不會發生改變,此時需要客戶根據實際應用來配置端口狀態來達到理想的功耗值,未用端口建議配置為模擬模式。
?其他的RTC等低功耗運行模塊因在深度休眠下高速時鐘停止運行,所以如果需要在深度休眠模式下運行RTC等模塊,需配置模塊時鐘源為LSI或LSE。
根據上述內容,可以配置CW32L083的低功耗應用的例程,具體的代碼可以查看CW32L083的固件庫中PWR_CurrentConsumption這一例程,配置PA04和PA05為引腳輸入,并開啟下降沿中斷,在中斷服務函數改變gKeyStatus的值,從而使得MCU在main中進入低功耗休眠模式。
volatile uint8_t gKeyStatus;
volatile uint32_t gFlagWakeUpIrq = 0;
int main(void)
{
RCC_HSI_Enable( RCC_HSIOSC_DIV6); //配置系統時鐘為HSI 8M
InitTick(8000000ul); //初始化SysTick
LED_Init(); //LED初始化
BSP_PB_Init(); //按鍵初始化
while (1)
{
gKeyStatus = 0;//在沒有進入低功耗模式前,PC03每間隔1s翻轉一次狀態
do
{
PC03_TOG(); //翻轉LED1
SysTickDelay(1000); //延遲1s.
} while (gKeyStatus == 0);
PC03_SETLOW(); //PC03置低
DeepSleepModeTest(); //進入深度睡眠模式
}
}
//按鍵初始化,設置PA05沿下降沿觸發中斷
void BSP_PB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOA時鐘
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk);
GPIO_InitStructure.Pins = GPIO_PIN_5;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_InitStructure.IT = GPIO_IT_FALLING;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_ConfigFilter(CW_GPIOA, GPIO_PIN_5, GPIO_FLTCLK_RC10K);
//設置GPIOA的中斷等級為3
NVIC_SetPriority(GPIOA_IRQn, 0x03);
GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN5_Msk );
NVIC_EnableIRQ(GPIOA_IRQn);
}
//LED I/O初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIO時鐘
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk);
GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
PC03_SETLOW();
}
void DeepSleepModeTest(void)
{
GPIO_InitTypeDef GPIO_InitStructure = { 0 };
PWR_InitTypeDef PWR_InitStructure = { 0 };
//打開GPIO時鐘
REGBITS_SET(CW_SYSCTRL->AHBEN,SYSCTRL_AHBEN_GPIOA_Msk|\
SYSCTRL_AHBEN_GPIOB_Msk | \
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Pins = GPIO_PIN_All;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
GPIO_Init(CW_GPIOF, &GPIO_InitStructure);
//關閉GPIO時鐘
REGBITS_CLR(CW_SYSCTRL->AHBEN,SYSCTRL_AHBEN_GPIOA_Msk| \
SYSCTRL_AHBEN_GPIOB_Msk | \
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
BSP_PB_Init(); //按鍵初始化
// 喚醒后自動使用內部高速時鐘(HSI)
RCC_WAKEUPCLK_Config(RCC_SYSCTRL_WAKEUPCLKEN);
PWR_InitStructure.PWR_Sevonpend = PWR_Sevonpend_Disable;
PWR_InitStructure.PWR_SleepDeep = PWR_SleepDeep_Enable;
PWR_InitStructure.PWR_SleepOnExit = PWR_SleepOnExit_Disable;
PWR_Config(&PWR_InitStructure);
PWR_GotoLpmMode();
SYSCLKConfig_DeepSleep();
LED_Init();
SysTickDelay(200);
PC02_SETHIGH();
}
}
//GPIOA中斷服務函數
void GPIOA_IRQHandler(void)
{
if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN5_Msk) > 0)
{
gKeyStatus = 1;
GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN5_Msk);//清除CW_GPIO中斷標志
}
}
上述代碼可以看到在未進入低功耗模式之前,LED1每1s翻轉一次,通過按鍵KEY2進入低功耗模式后,LED1燈滅,當再次按下KEY2后,重新回到正常的運行模式,LED1每一秒翻轉一次。通過測量可以得到,進入到低功耗模式之后,功耗顯著降低。
-
單片機
+關注
關注
6043文章
44621瀏覽量
638583 -
mcu
+關注
關注
146文章
17324瀏覽量
352655 -
微控制
+關注
關注
1文章
51瀏覽量
14525 -
32位MCU
+關注
關注
8文章
193瀏覽量
66804
發布評論請先 登錄
相關推薦
評論