定时器中断间歇性丢失

4
我正在运行一个STM32F072ZB,将其置于待机模式。MCU大部分时间都处于睡眠状态(每1小时唤醒一次以读取传感器)。由于我正在运行看门狗,我使用RTC每25秒钟生成一个警报(看门狗周期约为28秒)。所以当我睡觉1小时时,我会在当前时间加上25秒设置闹钟,然后进入待机模式,被警报唤醒并启动看门狗,然后设置下一个25秒的闹钟,如此循环...

这几乎完美运行,但出于某些原因,有时MCU由于未启动看门狗而重置。这意味着由于某种原因我错过了闹钟。我进行了一些测试,在24小时内发生了6次。

代码如下:

// Set RTC_Alarm
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
util_msDelay(10);

/*To configure the wake up timer to 25s the WakeUpCounter is set to 0xC738:
 Wakeup Time Base = 16 /(32.768 kHz RC) = ~0.49 ms
 Wakeup Time = ~0.49 ms  * WakeUpCounter
 Therefore, with wake-up counter =  0xC738  = 51.000
 Wakeup Time =  0.49 ms *  51,000 = ~ 25 sec. */

HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0xC738, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
util_msDelay(10);

if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) {
    /* Clear Standby flag */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}

/* Clear Wake-up timer flag if it is set    */
/* Flag will set after exiting from Standby */
if (LL_RTC_IsActiveFlag_WUT(RTC) == 1) {
    LL_RTC_ClearFlag_WUT(RTC);
}

/* Clear all related wakeup flags */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
util_msDelay(10);

这个问题有没有任何周期性?顺便问一下,睡眠模式下你的掉电复位电平是多少? - GabrielT
1个回答

5

STM32 IWDG使用LSI振荡器运行,名义上为40KHz,最大名义超时时间约为26.2秒,但RC振荡器既不准确也不稳定,可变性在30KHz到50KHz之间,从而导致计时变化19.65到32.75秒。

如果RTC也由LSI驱动,则没有问题,但如果您是从LSE驱动它的话,则不能保证RTC警报会在看门狗之前触发,因此您应将RTC警报设置为小于19秒。

也就是说,如果您从LSI运行RTC,则在名义上为40KHz时,25秒的计算是不正确的,51000只有20.4秒。 这是含糊的,因为评论建议您使用32768Hz的LSE,但它也说它是一个RC振荡器,其中我期望一个晶体或陶瓷振荡器。


对于 RC 的问题造成的误解很抱歉。计算是从 STM 的示例中复制粘贴过来的,他们使用了 RC。我正在使用 LSE。谢谢您的建议,我将尝试将 RTC 闹钟设置为少于 19 秒,并希望它能对问题有所帮助。 - AdiT
1
如果问题仍然存在,那么我们至少排除了一个可能的原因。虽然对于一个强大的应用程序,您确实需要考虑公差。它是可以校准的,我想热漂移远小于R/C值公差。19秒将是一个异常值,但从26秒到25秒的漂移是可信的。也许可以使用热枪/吹风机和冷冻喷雾进行测试,看看是否可以引发错误。 - Clifford
你是否熟悉STM32是否有一个计数看门狗的寄存器?我想在看门狗触发时捕获它,以查看可能的散布情况。 - AdiT
1
@AdiT:最好发布一个新问题。IWDG计数器无法读取。它运行在独立的时钟域上,即使可以读取,也会很复杂。一种解决方案是在重置看门狗的同时将常规定时器清零,然后在忙循环中连续将该计数器值写入SRAM,然后在重置后检查SRAM值(链接器需要设置为不初始化计数器空间)。这将为您提供每个看门狗重置所需的时间读数。正如我所说,如果您想要更全面的考虑,请发布一个新问题。 - Clifford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接