STM32CubeL4 固件库 V1.13.0 RTC
唤醒问题
前言
因为 STM32L4 极其出色的低功耗性能,越来越多的用户在使用 STM32L4 系列开发产品。谈到低功耗,自然就少不了低功耗
模式。进入低功耗模式,自然需要能够唤醒。很多用户在产品开发中会使用 RTC 的定时唤醒从低功耗状态。
问题
某客户在其产品的设计中,使用了 STM32L476RGT6。客户使用 RTC 的定时唤醒来将系统从 STOP2 模式中唤醒,但是发现
无法唤醒。
调研
1.了解问题
客户参考\STM32Cube_FW_L4_V1.13.0\Projects\NUCLEO-L476RG\Examples\PWR\PWR_STOP2_RTC 的代码,加入其工
程项目中,发现无法使用 RTC 将系统从 STOP2 模式中唤醒。电路跟客户以前的板子没有区别,觉得不会是电路的问题。为
了验证问题,使用了 NUCLEO-L476RG 板来跑这段例程,结果,发现此例程并没有如 readme.txt 中描述的那样,进入
STOP2 模式后经过大约 33 秒的时间后唤醒。按照 readme.txt 的说明,应该是 LED 先闪烁 5 秒,然后熄灭,进入 STOP2
式,RTC 定时 33 秒后将系统唤醒,再回到闪灯,如此循环。但是,实际上这个例程的结果是 LED 闪烁 5 秒后进入 STOP2
模式后就再也没有见到 LED 闪烁了,即死在 STOP2 模式了。
2.分析问题
为进一步确认问题,使用另一版本的固件库的相关例程\STM32Cube_FW_L4_V1.12.0\Projects\NUCLEO-
L476RG\Examples\PWR\PWR_STOP2_RTC 进行验证,结果却发现功能是正常的。难道客户描述有误?下载跟客户相同的
STM32CubeL4 版本库,即用 STM32Cube_FW_L4_V1.13.0 来进行验证,发现客户描述的问题确实存在。也就是说,
V1.12.0 V1.13.0 在这个例程上存在差异。检查 main.c 源代码,并没有存在区别。所以,猜测驱动代码出问题了。可能时
没有产生中断去唤醒 STOP2 模式,所以特别来检查一下 main.c 中调用的 RTC 唤醒定时器中断的配置函数。
HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0x0FFFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
HAL_RTCEx_SetWakeUpTimer_IT()函数位于 stm32l4xx_hal_rtc_ex.c 中。对比 V1.12.0 版本和 V1.13.0 版本中的这个函
数,发现在 V1.13.0 为了加入对 STM32L412 STM32L422 的支持,对此函数内容进行了修改。最后发现,在 V1.13.0 版本
中,修改后的这个函数出现了一个 Bug
#if defined(STM32L412xx) || defined(STM32L422xx)
/* In case of WUT autoclr, the IRQ handler should not be called */
if (WakeUpAutoClr != 0u)
{
/* RTC WakeUpTimer EXTI Configuration: Event configuration */
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT();
}
else
{
/* RTC WakeUpTimer EXTI Configuration: Interrupt configuration */
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
}
#else /* defined(STM32L412xx) || defined(STM32L422xx) */
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT(); //L912
#endif /* defined(STM32L412xx) || defined(STM32L422xx) */
L912 行的位置,也就是针对非 STM32L412/STM32L422 的部分,它使用的语句是:
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT();
而在 V1.12.0 中,使用的是:
/* RTC WakeUpTimer Interrupt Configuration: EXTI configuration */
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
这个看起来就很明显了,在 V1.13.0 中使能的是事件,而非中断。所以导致了 RTC 唤醒定时器事件没有产生中断。
3.问题解决
L912 行位置上的
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT();
修改为:
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
问题解决。
结论及处理
由于在\STM32Cube_FW_L4_V1.13.0\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rtc_ex.c 中存在的 bug 导致了
RTC 唤醒定时器中断无法产生中断,无法将系统从 STOP2 模式唤醒。
我们可以直接修复 bug 或者使用 STM32Cube_FW_L4_V1.14.0 版本的库。STM32Cube_FW_L4_V1.14.0 版本已修复此问
题,可参考\STM32Cube_FW_L4_V1.14.0\Drivers\STM32L4xx_HAL_Driver\Release_Notes.html 中的相关描述。
我们知道,STM32 系列众多,相应的固件库庞大且一直在不断丰富完善中,在怀疑驱动库代码方面问题时不妨进一步查看相
关实现代码或使用不同版本库代码做比较验证。