Arduino 多个计时器还是带有多个计数器的单个任务?

Arduino 多个计时器还是带有多个计数器的单个任务?,arduino,embedded,stm32,Arduino,Embedded,Stm32,假设您有一些函数必须在不同的时间点调用,但必须连续调用(恒定任务,如每250毫秒、每2秒、每5分钟)。 是否最好使用4-5个计时器,每个计时器专用于一个任务,还是最好在较小的任务中对所有内容进行编码,然后使用计数器变量运行另一个函数 e、 g 另外,假设您希望避免/防弹应对以下情况: 在做2秒的事情之前,你必须确保第8个250ms任务已经计算完毕 在做20分钟的工作之前,你必须确保第4800个250毫秒和第600个2秒的任务已经计算完毕 这个问题与最佳做法和绩效有关 此外,最好在回调中执行这

假设您有一些函数必须在不同的时间点调用,但必须连续调用(恒定任务,如每250毫秒、每2秒、每5分钟)。 是否最好使用4-5个计时器,每个计时器专用于一个任务,还是最好在较小的任务中对所有内容进行编码,然后使用计数器变量运行另一个函数

e、 g

另外,假设您希望避免/防弹应对以下情况:

  • 在做2秒的事情之前,你必须确保第8个250ms任务已经计算完毕

  • 在做20分钟的工作之前,你必须确保第4800个250毫秒和第600个2秒的任务已经计算完毕

这个问题与最佳做法和绩效有关


此外,最好在回调中执行这些计算,还是使用回调修改标志并在主循环中执行计算?

我假设您使用的是STM32,因为您标记了STM32

除非您的应用程序对时间要求非常严格,需要使用抢占式和异步计时器中断(例如,5分钟的任务非常重要,因此即使在运行一个单独的250ms回调任务时,也应该调用它),使用多个计时器中断只是浪费计时器,您需要使用尽可能少的中断。计算变量并不昂贵,所以这样做是可以的

真正需要考虑的是任务的长度。ISR应尽可能短,因此如果计时器回调任务很长,则应在主循环中使用标志和轮询操作。轮询标志更可取,尤其是在单个计时器ISR中使用多个回调时。想象一下,在ISR中调用250ms、2s和20min回调时,ISR所需的时间将是平时的3倍


顺便问一下,如果您决定使用单个计时器,为什么不使用?每个Cortex M MCU都提供SysTick定时器,其操作在MCU系列中是相同的。您可以很容易地将其配置为1ms中断计时器。只要在主循环中使用轮询,1ms中断必须是正常的。有许多关于Systick的教程(例如,和)

我假设您正在使用STM32,因为您标记了STM32

除非您的应用程序对时间要求非常严格,需要使用抢占式和异步计时器中断(例如,5分钟的任务非常重要,因此即使在运行一个单独的250ms回调任务时,也应该调用它),使用多个计时器中断只是浪费计时器,您需要使用尽可能少的中断。计算变量并不昂贵,所以这样做是可以的

真正需要考虑的是任务的长度。ISR应尽可能短,因此如果计时器回调任务很长,则应在主循环中使用标志和轮询操作。轮询标志更可取,尤其是在单个计时器ISR中使用多个回调时。想象一下,在ISR中调用250ms、2s和20min回调时,ISR所需的时间将是平时的3倍


顺便问一下,如果您决定使用单个计时器,为什么不使用?每个Cortex M MCU都提供SysTick定时器,其操作在MCU系列中是相同的。您可以很容易地将其配置为1ms中断计时器。只要在主循环中使用轮询,1ms中断必须是正常的。Systick上有许多教程(例如,和)

对于时间不太关键的任务,执行此操作的标准方法是实现一个计时器,该计时器每毫秒触发一次

然后,该计时器遍历已注册的“软件计时器”列表,并检查是否到了执行它们的时间。如果是这样,计时器将调用包含计时器特定代码的函数指针。即计时器驱动程序调用的回调函数


如果这些函数保持最小,例如仅设置一个标志,则可以从主计时器ISR执行它们。

对于时间不太关键的任务,执行此操作的标准方法是实现一个计时器,该计时器每毫秒触发一次

然后,该计时器遍历已注册的“软件计时器”列表,并检查是否到了执行它们的时间。如果是这样,计时器将调用包含计时器特定代码的函数指针。即计时器驱动程序调用的回调函数


如果这些功能保持最小,例如仅设置一个标志,则可以从主计时器ISR执行它们。

这里没有正确答案,最佳做法是实施设计以满足要求,因为项目的要求因项目而异,没有单一的正确答案。一个通用解决方案将无法适用于广泛的产品,另一个通用解决方案也是如此。您可以强制执行一个解决方案,但这可能会增加许多被黑客攻击的创可贴,只会增加项目的风险,可能导致失败或召回或现场升级,这些都是不必要的,会使产品和公司看起来很糟糕。进行系统工程,大多数时候正确的解决方案只会自动出现,而不进行系统工程,故障只会自动出现。

这里没有正确的答案,最佳做法是实施设计以满足要求,由于一个项目的要求因项目而异,所以没有单一的正确答案。一个通用解决方案将无法适用于广泛的产品,另一个通用解决方案也是如此。您可以强制执行一个解决方案,但这可能会增加许多被黑客攻击的创可贴,只会增加项目的风险,可能导致失败或召回或现场升级,这些都是不必要的,会使产品和公司看起来很糟糕。做你的系统工程,大多数情况下正确的解决方案将
//callback each 250ms
void 250ms_TASK(){
    if (counter % 8 != 0){ //250ms*8 = 2s
        return;
    }

    // do 2 sec stuff

    if (counter != 4800){ //250ms*4800 = 20min
        return;
    }
    //do 20min stuff
    counter = 0;
}