[STM32U0]【STM32U083测评】尝试LPUART的唤醒功能

阅读stm32u083的手册得知进入stop2低功耗模式后,uart是不能唤醒MCU的,只有LPUART具有此功能。 故而如果需要利用uart唤醒stop2模式下的mcu,只能使用LPUART。LPUART的时钟源可以是PCLK1, SYSCLK, HSI或LSE。进入stop2模式后,PCLK1和SYSCLK是关闭的,其实HSI时钟也是关闭的,但是手册里这么句话:“ Some peripherals with wake-up capability I2C3 and LPUART) can switch on the HSI16 to receive a frame, and switch off the HSI16 after receiving the frame if it is not a wake-up frame. In this case the HSI16 clock is propagated only to the peripheral requesting it”,所以像LPUART唤醒开启后,一旦有数据硬件上会临时打开HSI16,收完数据后自动关闭HSI16。这个功能非常有用,因为LSE频率32768HZ,LPUART如果用LSE做时钟源波特率上限比较低,如果又需要LPUART唤醒功能,又需要高波特率,HSI16为时钟源是唯一的路径

程序设计要点
选PA2/PA3针脚做LPUART TX/RX
阅读原理图后发现,STLINK的VCP TX/RX是接在PA2/PA3针脚,巧合的是PA2/PA3可以复用为LPUART的TX 与RX功能,这样测试比较方便不用另外接任何uart转接。

复制

 __HAL_RCC_GPIOA_CLK_ENABLE();

    /**LPUART1 GPIO Configuration

    PA3     ------> LPUART1_RX

    PA2     ------> LPUART1_TX

    */

    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


SystemClock_Config里开启HSI

复制

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;


HAL_UART_MspInit()里为LPUART选HSI为时钟源

复制

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;

    PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

    {

      Error_Handler();

    }



进入stop2模式前,LPUART唤醒的设置
这有固定套路,参阅样例代码比较合适,注释也比较清晰,这里不多费口舌

复制

  /* make sure that no LPUART transfer is on-going */

  while (__HAL_UART_GET_FLAG(&hlpuart1, USART_ISR_BUSY) == SET);

  /* make sure that LPUART is ready to receive

   * (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */

  while (__HAL_UART_GET_FLAG(&hlpuart1, USART_ISR_REACK) == RESET);



  /* set the wake-up event:

   * specify wake-up on RXNE flag */

  WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;

  if (HAL_UARTEx_StopModeWakeUpSourceConfig(&hlpuart1, WakeUpSelection) != HAL_OK)

  {

    Error_Handler();

  }



  /* Enable the UART Wake UP from STOP mode Interrupt */

  __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_WUF);



进入stop2模式与唤醒

复制

  /* enable MCU wake-up by LPUART */

  HAL_UARTEx_EnableStopMode(&hlpuart1);

  HAL_SuspendTick();

  /* enter STOP2 mode */

  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);



  /* ... STOP2 mode ... */



/* at that point, MCU has been awoken: LED4 has been turned back on */

  SystemClock_Config();



  /* Wake Up based on RXNE flag successful */

  HAL_UARTEx_DisableStopMode(&hlpuart1);


这里也是固定代码套路:进入stop模式前,调用HAL_UARTEx_EnableStopMode()使能LPUART唤醒,醒来后配置下时钟,以及调用HAL_UARTEx_DisableStopMode()关闭LPUART唤醒功能。要注意的是HAL_SuspendTick(),笔者测试如果没这行代码,MCU会立即被唤醒,估计是还未进入stop2模式,tick中断来了。

测试结果
进入stop2模式后,minicom下按任意键会成功唤醒MCU,并有期望的信息打印
---------------------
作者:xhackerustc
链接:https://bbs.21ic.com/icview-3379754-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值