STM32L051 low power STOP mode serial port interrupt wake

After STM32L051 STOP mode, wake-up by the RTC removed, but also by external interrupts, at stop without rtc mode current consumption can be achieved 0.4uA. Many times, we need to use the STM32 wake of the serial port, for example, after receiving a command to wake the MCU serial port related operations. This article summarizes the STOP mode STM32L051 by external interrupt "button, serial port" to wake up.

Serial wake idea is to STOP before entering the RX MCU set foot EXTI mode, and enable the corresponding interrupt, re-initialize the serial port after waking up, configure the clock. External actually use interrupt.

  1. The peripheral set before entering STOP mode, GPIO to be set to analog input status, cancel restore the default serial port configuration.
static void system_config_before_stop(void)
{
    GPIO_InitTypeDef GPIO_Initure;

    HAL_UART_DeInit(&huart1);
    /* 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_Initure.Pin = GPIO_PIN_All;
    GPIO_Initure.Mode = GPIO_MODE_ANALOG;
    GPIO_Initure.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);
    HAL_GPIO_Init(GPIOB, &GPIO_Initure);
    HAL_GPIO_Init(GPIOC, &GPIO_Initure);

    /* Disable GPIOs clock */
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
}
  1. Setting wake-up source interrupt here to configure the keys and serial RX-related interruptions.
static void stop_exit_config(void)
{
    GPIO_InitTypeDef GPIO_Initure = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_Initure.Pin = KEY_PIN;
    GPIO_Initure.Mode = GPIO_MODE_IT_RISING;
    GPIO_Initure.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(KEY_PORT, &GPIO_Initure);

    HAL_NVIC_SetPriority(EXTI2_3_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);

    GPIO_Initure.Pin = GPIO_PIN_10;
    GPIO_Initure.Mode = GPIO_MODE_IT_FALLING;
    GPIO_Initure.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);
    HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);

}
  1. Call the library functions into STOP mode.
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
  1. After exiting STOP mode to restore the clock. Special attention after entering the STOP mode, the system clock into a 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); //ͬʱÉèÖÃFLASHÑÓʱÖÜÆÚΪ1
    if (ret != HAL_OK) while (1);
}
  1. Restore individual peripheral states, such as GPIO, serial port initialization.
  2. Direct call function where you need to enter the STOP mode.
static void enter_stop_mode(void)
{
    //1. 配置stop之前各外设
    system_config_before_stop();

    //2.设置唤醒中断
    stop_exit_config();

    //3. 进入stop
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

    //3.退出stop后恢复各外设
    clock_config_after_stop();

	//4.恢复各外设
    gpioInit();
    uart1Init(115200);
}

Currently testing the current consumption is consistent with the data sheet.

Here Insert Picture Description
Attach project code, you can refer to a friend in need.

More, I welcome the attention of the public number. Sweep the micro-channel to follow the Fanger Wei code:
Micro channel scan code added public number: TonyCode

Published 63 original articles · won praise 250 · Views 230,000 +

Guess you like

Origin blog.csdn.net/TonyIOT/article/details/99636969