充分利用开发板上所有的计时器。
音响、方波、延迟任务、定时重复,这些任务都需要应用开发板上的计时器才能完成。有时你甚至需要多个计时器同步运行,实现多线程任务。但是,当前Arduino社区并没有提供比较完善的计时器运行库。它们能够执行的任务模式非常有限,而且用户无法指定具体要使用哪个计时器。其结果就是,经常有一些使用计时器的库发生冲突,或者和用户自己的应用发生冲突。本项目旨在将计时器可能需要使用的所有功能在所有计时器上实现,最关键的是允许用户手动指定要使用的硬件计时器,避免冲突。
如果有其他与计时器相关的库与本库一起使用,则可能会发生计时器冲突。请先查阅那些库的文档、代码,确认它们使用了哪些硬件计时器,然后在本库的HardwareTimers.hpp中注释掉相应的宏定义,那样本库就会不再占用那些计时器。
此架构编译器必须启用C++17。打开“%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr<版本号>\platform.txt”并将参数“-std=gnu++11”更改为-std=gnu++17。此架构最多支持0~5共6个计时器。
HardwareTimer0
,该计时器有8位,即$2^8=256$个计时状态,支持COMPA和COMPB中断,但不支持OVF中断,因为该中断被内置函数millis();delay();micros();
占用了。本库考虑到这个情况,用COMPA和COMPB中断同样能实现所有的计时功能,因此该计时器仍然可用,但会付出一些微妙的性能代价。此外,一旦使用此计时器后,再使用相关内置函数将产生未定义行为。因此,您仍应避免使用该计时器,除非其它计时器都处于繁忙状态。
HardwareTimer1/3/4/5
,这些计时器都具有16位,即65536个计时状态,因此比8位计时器更精确。COMPA、COMPB和OVF三个中断都为可用。绝大多数情况下,这些计时器是您的首选。注意,3~5号计时器仅在Mega2560系列开发板中支持。
HardwareTimer2
该计时器也是8位,但和0号计时器有些方面不同:
- 该计时器支持7种预分频模式,而所有其它计时器都只支持5种。因此该计时器比0号略微精确一些,但仍不如16位计时器。如果尚有空闲的16位计时器,应避免使用该计时器。
- 和16位计时器一样,该计时器的COMPA、COMPB和OVF中断都可用,没有被内置函数占用。
本架构部分代码参考DueTimer。此架构有11个计时器可用:
PeripheralTimers[]
,周边计时器,这些是绝大多数情况下应尽可能使用的计时器,具有32位计数和84㎒精度,是最通用、精确且无副作用的计时器
RealTimer
,实时计时器,具有32位计数和29.4㎑精度。较长的计时周期(跨天级别)中,通常对精度要求不高,使用此计时器可以降低功耗。由于人耳最高可听到约达20㎑的声音,与此计时器精度接近,在高音频段能够听出明显的音调偏差,一般不宜将此计时器用于产生音频。
SystemTimer
,系统计时器,具有24位计数和84㎒精度。但是,此计时器为一些内置函数如millis();delay();micros();
等依赖,使用系统计时器后再调用这些内置函数将产生未定义行为。一般应避免使用系统计时器。
根据计时任务类型的不同,可能需要执行最多三个步骤以实现预期功能:获取HardwareTimer
、创建任务、执行任务。
几乎所有任务的创建都需要先获取HardwareTimer
,例外是SAM架构上的DelayTask
和TimingTask
,它们使用独立的主计时器实现而不需要HardwareTimer
。
你可以选择手动指定HardwareTimer
编号,或者让本库自动为你分配。