STM32
直播中

陈利妮

7年用户 978经验值
私信 关注
[问答]

stm32L475在rtc和gpio中断唤醒后,发现串口不能收发数据了,怎么解决?

在stop1模式下,设置rtc,gpio中断,usart1都可唤醒mcu,但是在rtc和gpio中断唤醒后,发现串口不能收发数据了,再次休眠后串口能唤醒。但是在由usart1唤醒的情况下,串口还是可以通讯使用,请问哪位高手能指点下!


void PrepareUSARTToStopMode(void)
{

  /* Empty RX Fifo before entering Stop mode 1 (Otherwise, characters already present in FIFO
     will lead to immediate wake up */
  while (LL_USART_IsActiveFlag_RXNE(USART1))
  {
    /* Read Received character. RXNE flag is cleared by reading of RDR register */
    ubReceivedChar = LL_USART_ReceiveData8(USART1);
  }

  /* Clear OVERRUN flag */
  LL_USART_ClearFlag_ORE(USART1);

  /* Make sure that no USART transfer is on-going */
  while(LL_USART_IsActiveFlag_BUSY(USART1) == 1)
  {
  }
  /* Make sure that USART is ready to receive */   
  while(LL_USART_IsActiveFlag_REACK(USART1) == 0)
  {
  }

  /* About to enter stop mode: switch off LED */
  //LED_G_TogglePin;

  /* Configure USART1 transfer interrupts : */
  /* Clear WUF flag and enable the UART Wake Up from stop mode Interrupt */
  LL_USART_ClearFlag_WKUP(USART1);
  LL_USART_EnableIT_WKUP(USART1);

  /* Enable Wake Up From Stop */
  LL_USART_EnableInStopMode(USART1);
}




void Configure_USART1(void)
{
  /* (1) Enable GPIO clock and configures the USART1 pins **********************/
  /*    (TX on PA.9, RX on PA.10)                     **********************/

  /* Enable the peripheral clock of GPIOA */
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);

  /* Configure TX Pin as : Alternate function, High Speed, PushPull, Pull up */
  LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
  LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_7);
  LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_PUSHPULL);
  LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_NO);

  /* Configure RX Pin as : Alternate function, High Speed, PushPull, Pull up */
  LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_10, LL_GPIO_MODE_ALTERNATE);
  LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_10, LL_GPIO_AF_7);
  LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_10, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_10, LL_GPIO_OUTPUT_PUSHPULL);
  LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_10, LL_GPIO_PULL_NO);

  /* (2) NVIC Configuration for USART1 interrupts */
  /*  - Set priority for USART1_IRQn */
  /*  - Enable USART1_IRQn           */


  NVIC_SetPriority(USART1_IRQn, 0);  
  NVIC_EnableIRQ(USART1_IRQn);

  /* (3) Enable the USART1 peripheral clock and clock source ****************/
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);

  /* Set USART1 clock source as HSI */
  LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_HSI);

  /* (4) Configure USART1 functional parameters ********************************/

  /* Disable USART1 prior modifying configuration registers */
  /* Note: Commented as corresponding to Reset value */
  // LL_USART_Disable(USART1);

  /* TX/RX direction */
  LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX);

  /* 8 data bit, 1 start bit, 1 stop bit, no parity */
  LL_USART_ConfigCharacter(USART1, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);

  /* No Hardware Flow control */
  /* Reset value is LL_USART_HWCONTROL_NONE */
  // LL_USART_SetHWFlowCtrl(USART1, LL_USART_HWCONTROL_NONE);

  /* Oversampling by 16 */
  /* Reset value is LL_USART_OVERSAMPLING_16 */
  // LL_USART_SetOverSampling(USART1, LL_USART_OVERSAMPLING_16);

  /* Set Baudrate to 9600 using HSI frequency set to HSI_VALUE */
  LL_USART_SetBaudRate(USART1, HSI_VALUE, LL_USART_OVERSAMPLING_16, 9600);

  /* Set the wake-up event type : specify wake-up on RXNE flag */
  LL_USART_SetWKUPType(USART1, LL_USART_WAKEUP_ON_RXNE);

//  LL_USART_EnableIT_RXNE(USART1); //开启接收中断

  /* (5) Enable USART1 **********************************************************/
  LL_USART_Enable(USART1);

  /* Polling USART initialisation */
  //while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1))))
  //{
  //}
}




void Stop_Mode_Config(void)
{
        
        __HAL_RCC_PWR_CLK_ENABLE();
        
          /* Ensure that MSI is wake-up system clock */
          __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
          /* USER CODE END 2 */
        

        Configure_USART1();
        PrepareUSARTToStopMode();
        
        HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);

        SystemClock_Config();
        uart_init(9600);
        IIC_Init();
        //HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
}


回帖(2)

刘飞

2024-4-18 09:52:54
唤醒后重新配置一下串口呢
举报

张国厚

2024-4-18 18:11:17
首先,请确保你的代码中正确地配置了串口的中断使能和优先级。
在Stop模式下,MCU会进入低功耗模式,所以除了RTC和GPIO中断外,其它外设都会被关闭。当MCU从低功耗模式唤醒时,它会恢复到正常工作模式,并自动开启被配置为唤醒源的中断。 所以你需要确认在唤醒后是否正确地初始化和使能了串口。

如果你的串口设置正常,但在唤醒后无法收发数据,可能是由于以下原因:
1. 确保串口中断设置正确:检查中断优先级设置,并确保中断回调函数中清除了对应的中断标志位。
2. 确保串口的时钟源:在低功耗模式下,MCU的时钟源可能被切换到低功耗RC时钟,而不是主时钟。你可以尝试在唤醒后重新配置串口的时钟源。

如果以上方法都不能解决问题,可以尝试打印调试信息以查看具体是什么导致了串口无法收发数据。您还可以尝试使用示波器或逻辑分析仪检查串口通信线路和信号。

希望这些信息对您有帮助!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分