简体   繁体   中英

Uart doesn't work after waking up from stop mode in stm32f4

I am using STOP mode to save power and also deinitialize GPIO to achieve maximum power saving. In this case current consumption goes below 1mA. I am using UART Rx pin as external interrupt to wake up board from STOP mode. The board does wake up but UART or other peripheral like DCMI doesn't work. Following is my code.

void MX_GPIO_Deinit()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Pin = GPIO_PIN_All;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
    /* Disable GPIOs clock */
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOH_CLK_DISABLE();
}

void stopMode(void)
{
  HAL_SuspendTick();
  MX_GPIO_Deinit();
  __HAL_RCC_PWR_CLK_ENABLE();
  HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);

  GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_GPIOA_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}

void resumeStopMode(void)
{
    SystemClock_Config();
    HAL_ResumeTick();
    MX_GPIO_Init();

    HAL_UART_MspInit(&huart4);
    HAL_I2C_MspInit(&hi2c2);
    HAL_DCMI_MspInit(&hdma_dcmi);
    HAL_TIM_MspPostInit(&htim1);
    MX_DMA_Init();
    MX_UART4_Init();
    MX_I2C2_Init();
    MX_DCMI_Init();
    MX_TIM1_Init();

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}

int getChar()
{
   uint8_t InputData = 0;
   TimmingDelay = 50000;
   while (TimmingDelay !=0)
   {
       if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE))
           __HAL_UART_CLEAR_OREFLAG(&huart4);

       if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE))
       {
           InputData = huart4.Instance->DR & 0x1FF;
           return InputData;
       }
   }
   return -1;
}

void main(void)
{
    stopMode()
    resumeStopMode() /* woken up by uart interrupt*/
    int receivedByte = 0;
    receivedByte = getChar() /* This line doesn't work after waking it goes into stop mode */
}

Since I deinitialize all GPIO I am not able to to debug. How can I make UART work properly after waking up from STOP mode.

There is a wake-up latency associated with STOP mode to allow the HSI RC oscillator to wake up and potentially flash and the internal regulator. If the first byte is corrupt then it is most likely that it is a result of this latency.

This is my solution.

          HAL_UART_MspInit(&huart4);
          __HAL_UART_DISABLE(&huart4);
          __HAL_UART_ENABLE(&huart4);

but following do not work.

          HAL_UART_Init(&huart4);

I ran into almost this exact same issue and here was my solution (keep in mind I'm using UART2):

    HAL_UART_MspInit(&huart2);
    MX_USART2_UART_Init();

The reason that just calling the normal MX_USART2_UART_Init() function doesn't work is because the UART peripheral has state and wont re-initialize clocks if its state doesn't think it needs to:

    Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c

    308 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
    309 {
    .
    .
    .
    327   if (huart->gState == HAL_UART_STATE_RESET)
    328   {
    .
    .
    .
    343     /* Init the low level hardware : GPIO, CLOCK */
    344     HAL_UART_MspInit(huart);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM