/Timers_one_for_all

Make full use of all your hardware timers on your Arduino board.

Primary LanguageC++GNU General Public License v3.0GPL-3.0

充分利用开发板上所有的计时器。

音响、方波、延迟任务、定时重复,这些任务都需要应用开发板上的计时器才能完成。有时你甚至需要多个计时器同步运行,实现多线程任务。但是,当前Arduino社区并没有提供比较完善的计时器运行库。它们能够执行的任务模式非常有限,而且用户无法指定具体要使用哪个计时器。其结果就是,经常有一些使用计时器的库发生冲突,或者和用户自己的应用发生冲突。本项目旨在将计时器可能需要使用的所有功能在所有计时器上实现,最关键的是允许用户手动指定要使用的硬件计时器,避免冲突。

硬件计时器

如果有其他与计时器相关的库与本库一起使用,则可能会发生计时器冲突。请先查阅那些库的文档、代码,确认它们使用了哪些硬件计时器,然后在本库的HardwareTimers.hpp中注释掉相应的宏定义,那样本库就会不再占用那些计时器。

ARDUINO_ARCH_AVR

此架构编译器必须启用C++17。打开“%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr<版本号>\platform.txt”并将参数“-std=gnu++11”更改为-std=gnu++17。此架构最多支持0~5共6个计时器。

TOFA_TIMER0

HardwareTimer0,该计时器有8位,即$2^8=256$个计时状态,支持COMPA和COMPB中断,但不支持OVF中断,因为该中断被内置函数millis();delay();micros();占用了。本库考虑到这个情况,用COMPA和COMPB中断同样能实现所有的计时功能,因此该计时器仍然可用,但会付出一些微妙的性能代价。此外,一旦使用此计时器后,再使用相关内置函数将产生未定义行为。因此,您仍应避免使用该计时器,除非其它计时器都处于繁忙状态。

TOFA_TIMER1 TOFA_TIMER3 TOFA_TIMER4 TOFA_TIMER5

HardwareTimer1/3/4/5,这些计时器都具有16位,即65536个计时状态,因此比8位计时器更精确。COMPA、COMPB和OVF三个中断都为可用。绝大多数情况下,这些计时器是您的首选。注意,3~5号计时器仅在Mega2560系列开发板中支持。

TOFA_TIMER2

HardwareTimer2该计时器也是8位,但和0号计时器有些方面不同:

  • 该计时器支持7种预分频模式,而所有其它计时器都只支持5种。因此该计时器比0号略微精确一些,但仍不如16位计时器。如果尚有空闲的16位计时器,应避免使用该计时器。
  • 和16位计时器一样,该计时器的COMPA、COMPB和OVF中断都可用,没有被内置函数占用。

ARDUINO_ARCH_SAM

本架构部分代码参考DueTimer。此架构有11个计时器可用:

TOFA_TIMER0~8

PeripheralTimers[],周边计时器,这些是绝大多数情况下应尽可能使用的计时器,具有32位计数和84㎒精度,是最通用、精确且无副作用的计时器

TOFA_REALTIMER

RealTimer,实时计时器,具有32位计数和29.4㎑精度。较长的计时周期(跨天级别)中,通常对精度要求不高,使用此计时器可以降低功耗。由于人耳最高可听到约达20㎑的声音,与此计时器精度接近,在高音频段能够听出明显的音调偏差,一般不宜将此计时器用于产生音频。

TOFA_SYSTIMER

SystemTimer,系统计时器,具有24位计数和84㎒精度。但是,此计时器为一些内置函数如millis();delay();micros();等依赖,使用系统计时器后再调用这些内置函数将产生未定义行为。一般应避免使用系统计时器。

使用入门

根据计时任务类型的不同,可能需要执行最多三个步骤以实现预期功能:获取HardwareTimer、创建任务、执行任务。

获取HardwareTimer

几乎所有任务的创建都需要先获取HardwareTimer,例外是SAM架构上的DelayTaskTimingTask,它们使用独立的主计时器实现而不需要HardwareTimer

你可以选择手动指定HardwareTimer编号,或者让本库自动为你分配。