很多MCU都有低功耗模式抬虽,以滿足對功耗要求苛刻的應(yīng)用場景脑题。STM32系列MCU的低功耗模式根據(jù)其內(nèi)核與類型的不同也各不相同许师,網(wǎng)上有很多文章介紹肉渴。本文總結(jié)下STM32L051的STOP模式公荧,通過RTC喚醒。
STM32L051在低功耗方面性能優(yōu)異同规,ST官方數(shù)據(jù)手冊中說明循狰,在stop without rtc模式下電流消耗能達(dá)到0.4uA,在stop with rtc模式下電流消耗能達(dá)到0.8uA券勺。
- 在進(jìn)入STOP模式前對外設(shè)進(jìn)行設(shè)置绪钥,GPIO要設(shè)置成模擬輸入狀態(tài)。
static void system_config_before_stop(void)
{
HAL_StatusTypeDef ret = HAL_OK;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable Ultra low power mode */
HAL_PWREx_EnableUltraLowPower();
/* Enable the fast wake up from Ultra low power mode */
HAL_PWREx_EnableFastWakeUp();
/* Select HSI as system clock source after Wake Up from Stop mode */
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
/* Enable GPIOs clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
GPIO_InitStructure.Pin = GPIO_PIN_All;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
/* Configure RTC */
RTCHandle.Instance = RTC;
RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
ret = HAL_RTC_Init(&RTCHandle);
if (ret != HAL_OK) while (1);
}
- 設(shè)置RTC的喚醒時間关炼,函數(shù)參數(shù)單位為秒程腹。
static void stop_rtc_config(uint32_t sleep)
{
/* Disable Wakeup Counter */
HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
/*## Setting the Wake up time */
HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, sleep, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
}
- 調(diào)用庫函數(shù)進(jìn)入STOP模式。
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
- 退出STOP模式后要恢復(fù)時鐘儒拂。特別注意在進(jìn)入STOP模式后系統(tǒng)時鐘變成了MSI寸潦。
static void clock_config_after_stop(void)
{
HAL_StatusTypeDef ret = HAL_OK;
RCC_OscInitTypeDef RCC_OscInitStructure = {0};
RCC_ClkInitTypeDef RCC_ClkInitStructure = {0};
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Get the Oscillators configuration according to the internal RCC registers */
HAL_RCC_GetOscConfig(&RCC_OscInitStructure);
/* After wake-up from STOP reconfigure the system clock: Enable HSI and PLL */
RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStructure.HSEState = RCC_HSE_OFF;
RCC_OscInitStructure.HSIState = RCC_HSI_ON;
RCC_OscInitStructure.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStructure.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStructure.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStructure.PLL.PLLMUL = RCC_PLLMUL_4;
RCC_OscInitStructure.PLL.PLLDIV = RCC_PLLDIV_2;
ret = HAL_RCC_OscConfig(&RCC_OscInitStructure);
if (ret != HAL_OK) while (1);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStructure.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStructure, FLASH_LATENCY_1);
if (ret != HAL_OK) while (1);
}
- 恢復(fù)各外設(shè)狀態(tài),比如GPIO社痛、串口等初始化见转。
static void gpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA1 */
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
}
- 在需要進(jìn)入STOP模式的地方直接調(diào)用函數(shù)。
static void enter_stop_rtc_mode(void)
{
//1. 配置stop之前各外設(shè)
system_config_before_stop();
//2.設(shè)置rtc喚醒時間20s
stop_rtc_config(20);
//3. 進(jìn)入stop
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
//3.退出stop后恢復(fù)時鐘
clock_config_after_stop();
//4.恢復(fù)各外設(shè)
gpioInit();
}
對于低功耗產(chǎn)品開發(fā)蒜哀,CPU的低功耗只是一部份斩箫,外圍電路設(shè)計上也要綜合考慮。目前測試到消耗電流比數(shù)據(jù)手冊高凡怎。