STM32L系列芯片 Stop状态唤醒的坑

最近在使用STM32L071C8Tx芯片做低功耗项目时,遇到了一个奇怪的Bug:
USART1 115200波特率 HSI时钟源(HSI RC Div 4分频 输出频率4M)
按照官方手册及HAL库提供的函数,使用 HAL_UARTEx_EnableStopMode()

允许串口Rx数据包将MCU从Stop状态唤醒,并使用HAL_UART_Receive_IT()

使能串口中断方式接收后进入Stop状态,上位机发送1字节数据极小概率能唤醒MCU。检测发现数据发送后MCU有将HSI时钟重新上电,并USART1中断有进入,但很快又关闭了HSI时钟,重新进入Stop状态。
由于STOP模式无法使用Debug,因此未找到具体中断源。
怀疑中断后未正确清空各中断Flag和置位各中断Enable位,但排查后并未找到原因。
官方手册描述了一种可能的情况会导致重新进入Stop状态:
STM32L系列芯片 Stop状态唤醒的坑_第1张图片并且提醒了使用串口唤醒Stop状态有波特率限制:
STM32L系列芯片 Stop状态唤醒的坑_第2张图片考虑可能问题出在MCU检测到Rx数据包时序不正确,所以并未生成唤醒事件,导致MCU并未从Stop状态唤醒。计算后发现串口波特率在容许的波特率范围内,问题并未出在外部唤醒信号上。
手册接下来描述了各低功耗模式下串口的工作状况,其中有一个细节:
STM32L系列芯片 Stop状态唤醒的坑_第3张图片
这里对于串口时钟源的要求从前文的HSI变为HSI16,猜想Bug可能是由于Stop状态唤醒时的时钟配置与自己设定的时钟配置不同,RCC_HSI_DIV被关闭,而不是先前配置的DIV4,从而导致USART1工作时钟错误,进而导致误判Rx信号并不是数据包(波特率校验错误?)最终取消了唤醒,关闭HSI时钟继续Stop状态。
根据这个猜想,将HSI分频器关闭,Bug消失。Stop状态下任一Rx数据包皆能唤醒MCU。
由于低功耗需求,HSI需要4分频后作为SYSCLK。改变思路,在USART1_IRQ_Handler()里首先使用SystemClock_Config()函数重新配置时钟,时钟正确后再进入HAL_UART_IRQHandler()进行中断处理。Bug同样消失。

感想:STM32的从STOP状态唤醒时一定要注意时钟是否为预期的工作状态,否则会导致一些奇怪的问题出现!

你可能感兴趣的:(STM32L系列芯片 Stop状态唤醒的坑)