From b114560517988975d5cc74313d8e87600c8c762b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9F=83=E5=8D=9A=E6=8B=89=E9=85=B1?= Date: Tue, 6 Jul 2021 14:18:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=E5=9C=A8=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=B1=BB=E4=BB=BB=E5=8A=A1=E7=BB=93=E6=9D=9F=E5=90=8E=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E4=B8=80=E4=B8=AA=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 36 ++++++++-------- library.properties | 2 +- src/Internal/DoAfter.h | 4 +- src/Internal/Kernel.h | 62 ++++++++++++++++----------- src/Internal/PlayTone.h | 10 ++--- src/Internal/RepeatAfter.h | 8 ++-- src/Internal/SquareWave.h | 85 +++++++++++++++++++++----------------- 7 files changed, 117 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 55d3bd4..2c118f4 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ void DoAfter(uint16_t AfterMilliseconds); //Repetitively and infinitely call your function with a timer interrupt for each IntervalMilliseconds. The first interrupt happens after IntervalMilliseconds, too. template void RepeatAfter(); -//仅重复有限次数 -//Repeat for only RepeatTimes -template +//仅重复有限次数,重复全部结束后触发DoneCallback回调 +//Repeat for only RepeatTimes. After all repeats done, DoneCallback is called. +template void RepeatAfter(); -//允许运行时动态设置毫秒数。重复次数不指定的话则为无限重复。 -//Specify milliseconds at runtime -template +//允许运行时动态设置毫秒数。重复次数不指定的话则为无限重复。重复全部结束后触发DoneCallback回调 +//Specify milliseconds at runtime. After all repeats done, DoneCallback is called. +template void RepeatAfter(uint16_t IntervalMilliseconds); //将当前时刻设为0,计量经过的毫秒数。读取MillisecondsElapsed变量来获得经过的毫秒数。 @@ -79,26 +79,26 @@ static volatile uint16_t MillisecondsElapsed; //Play a tone of FrequencyHz on PinCode endlessly. template void PlayTone(); -//只播放限定的毫秒数 -//Play for only given Milliseconds -template +//只播放限定的毫秒数。播放结束后触发DoneCallback回调 +//Play for only given Milliseconds. After the tone ended, DoneCallback is called. +template void PlayTone(); -//允许运行时动态设置毫秒数。 -//Specify milliseconds at runtime -template +//允许运行时动态设置毫秒数。播放结束后触发DoneCallback回调 +//Specify milliseconds at runtime. After the tone ended, DoneCallback is called. +template void PlayTone(uint16_t Milliseconds); //在引脚上生成无限循环的方波。不同于音调,这里可以指定高电平和低电平的不同时长 //Generate an infinite sequence of square wave. The high level and low level can have different time length. template void SquareWave() -//仅生成有限个周期数的方波 -//Generate the square wave for only RepeatTimes cycles. -template +//仅生成有限个周期数的方波。周期全部结束后触发DoneCallback回调 +//Generate the square wave for only RepeatTimes cycles. After all cycles done, DoneCallback is called. +template void SquareWave() -//允许运行时动态设置毫秒数。重复次数不指定的话则为无限重复。 -//Specify milliseconds at runtime -template +//允许运行时动态设置毫秒数。重复次数不指定的话则为无限重复。周期全部结束后触发DoneCallback回调 +//Specify milliseconds at runtime. After all cycles done, DoneCallback is called. +template void SquareWave(uint16_t HighMilliseconds, uint16_t LowMilliseconds) //阻塞当前代码执行指定毫秒数 diff --git a/library.properties b/library.properties index 825b578..bbac56c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TimersOneForAll -version=1.1.1 +version=1.2.0 author=EbolaChan maintainer=EbolaChan sentence=Make full use of all your hardware timers on your Arduino board. 充分利用你开发板上所有的硬件计时器 diff --git a/src/Internal/DoAfter.h b/src/Internal/DoAfter.h index d45c2e8..6866f9d 100644 --- a/src/Internal/DoAfter.h +++ b/src/Internal/DoAfter.h @@ -7,13 +7,13 @@ namespace TimersOneForAll void DoAfter() { constexpr Internal::TimerSetting TS = Internal::GetTimerSetting(TimerCode, AfterMilliseconds); - Internal::SLRepeaterSet(); + Internal::SLRepeaterSet(); } //在指定毫秒数后执行任务 template void DoAfter(uint16_t AfterMilliseconds) { Internal::TimerSetting TS = Internal::GetTimerSetting(AfterMilliseconds); - Internal::SLRepeaterSet(TS.TCNT, TS.PrescalerBits); + Internal::SLRepeaterSet(TS.TCNT, TS.PrescalerBits); } } \ No newline at end of file diff --git a/src/Internal/Kernel.h b/src/Internal/Kernel.h index fa8ba0d..2147317 100644 --- a/src/Internal/Kernel.h +++ b/src/Internal/Kernel.h @@ -5,7 +5,7 @@ namespace TimersOneForAll { //礼品API:虽然跟本库主题不合,但本库实际上用到了,并且觉得你可能也会感兴趣 namespace Gifts - { + { //快速翻转引脚电平,比digitalWrite性能更高 template void EfficientDigitalToggle() @@ -209,7 +209,7 @@ namespace TimersOneForAll #pragma endregion #pragma region 全模板实现 //Compa0表示自我重复,不切换 - template + template void Compa0() { if (!--SR) @@ -217,14 +217,18 @@ namespace TimersOneForAll if (InfiniteLr || --LR) SR = SmallRepeats; else + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } DoTask(); } } - template + template void Compa2(); //Compa1是小重复,结束后要切换到大重复,但是大重复有可能是COMPA也可能是OVF - template + template void Compa1() { if (!--SR) @@ -232,7 +236,7 @@ namespace TimersOneForAll if (Tcnt2 < TimerMax[TimerCode]) { SetOCRA(Tcnt2); - COMPA = Compa2; + COMPA = Compa2; } else TIMSK = 1; @@ -240,7 +244,7 @@ namespace TimersOneForAll } } //Compa2是大重复,结束后要执行动作,如果有重复次数还要切换到小重复 - template + template void Compa2() { if (!--SR) @@ -250,18 +254,22 @@ namespace TimersOneForAll if (Tcnt2 < TimerMax[TimerCode]) { SetOCRA(Tcnt1); - COMPA = Compa1; + COMPA = Compa1; } else TIMSK = 2; SR = SR1; } else + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } DoTask(); } } - template + template void SLRepeaterSet() { TIMSK = 0; @@ -291,12 +299,12 @@ namespace TimersOneForAll SR = SR1; if (SR2) { - COMPA = Compa1; + COMPA = Compa1; if (Tcnt2 == TM) - OVF = Compa2; + OVF = Compa2; } else - COMPA = Compa0; + COMPA = Compa0; SetTCNT(0); TIFR = 255; TIMSK = 2; @@ -304,7 +312,7 @@ namespace TimersOneForAll else { SR = IdealRepeats; - OVF = Compa0; + OVF = Compa0; if (Timer02) TCCRA = 0; else @@ -326,7 +334,7 @@ namespace TimersOneForAll template static volatile uint16_t SR2; //Compa0表示自我重复,不切换 - template + template void Compa0() { if (!--SR) @@ -334,14 +342,18 @@ namespace TimersOneForAll if (InfiniteLr || --LR) SR = SR1; else + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } DoTask(); } } - template + template void Compa2(); //Compa1是小重复,结束后要切换到大重复,但是大重复有可能是COMPA也可能是OVF - template + template void Compa1() { if (!--SR) @@ -351,13 +363,13 @@ namespace TimersOneForAll else { SetOCRA(Tcnt2); - COMPA = Compa2; + COMPA = Compa2; } SR = SR2; } } //Compa2是大重复,结束后要执行动作,如果有重复次数还要切换到小重复 - template + template void Compa2() { if (!--SR) @@ -369,16 +381,20 @@ namespace TimersOneForAll else { SetOCRA(Tcnt1); - COMPA = Compa1; + COMPA = Compa1; } SR = SR1; } else + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } DoTask(); } } - template + template void SLRepeaterSet(uint32_t TCNT, uint8_t PrescalerBits) { TIMSK = 0; @@ -410,12 +426,12 @@ namespace TimersOneForAll bool UseOvf = Tcnt2 == TM; if (SR2) { - COMPA = UseOvf ? Compa1 : Compa1; + COMPA = UseOvf ? Compa1 : Compa1; if (Tcnt2 == TM) - OVF = UseOvf ? Compa2 : Compa2; + OVF = UseOvf ? Compa2 : Compa2; } else - COMPA = Compa0; + COMPA = Compa0; SetTCNT(0); TIFR = 255; TIMSK = 2; @@ -423,7 +439,7 @@ namespace TimersOneForAll else { SR = SR1; - OVF = Compa0; + OVF = Compa0; if (Timer02) TCCRA = 0; else diff --git a/src/Internal/PlayTone.h b/src/Internal/PlayTone.h index 3469691..78e72a1 100644 --- a/src/Internal/PlayTone.h +++ b/src/Internal/PlayTone.h @@ -8,22 +8,22 @@ namespace TimersOneForAll { constexpr Internal::TimerSetting TS = Internal::GetTimerSetting(TimerCode, 500.f / FrequencyHz); Gifts::EfficientDigitalToggle(); - Internal::SLRepeaterSet>(); + Internal::SLRepeaterSet, -1, nullptr>(); } //播放有限的毫秒数 - template + template void PlayTone() { constexpr Internal::TimerSetting TS = Internal::GetTimerSetting(TimerCode, 500.f / FrequencyHz); Gifts::EfficientDigitalToggle(); - Internal::SLRepeaterSet, uint32_t(FrequencyHz) * Milliseconds / 500>(); + Internal::SLRepeaterSet, uint32_t(FrequencyHz) * Milliseconds / 500, DoneCallback>(); } //播放有限的毫秒数 - template + template void PlayTone(uint16_t Milliseconds) { constexpr Internal::TimerSetting TS = Internal::GetTimerSetting(TimerCode, 500.f / FrequencyHz); Gifts::EfficientDigitalToggle(); - Internal::SLRepeaterSet>(uint32_t(FrequencyHz) * Milliseconds / 500); + Internal::SLRepeaterSet, uint32_t(FrequencyHz) * Milliseconds / 500, DoneCallback>(TS.TCNT, TS.PrescalerBits); } } \ No newline at end of file diff --git a/src/Internal/RepeatAfter.h b/src/Internal/RepeatAfter.h index 0b9bef4..8a20d32 100644 --- a/src/Internal/RepeatAfter.h +++ b/src/Internal/RepeatAfter.h @@ -3,17 +3,17 @@ namespace TimersOneForAll { //每隔指定毫秒数重复执行任务。重复次数若为负数,或不指定重复次数,则默认无限重复 - template + template void RepeatAfter() { constexpr Internal::TimerSetting TS = Internal::GetTimerSetting(TimerCode, IntervalMilliseconds); - Internal::SLRepeaterSet(); + Internal::SLRepeaterSet(); } //每隔指定毫秒数重复执行任务。重复次数若为负数,或不指定重复次数,则默认无限重复 - template + template void RepeatAfter(uint16_t IntervalMilliseconds) { Internal::TimerSetting TS = Internal::GetTimerSetting(IntervalMilliseconds); - Internal::SLRepeaterSet(TS.TCNT, TS.PrescalerBits); + Internal::SLRepeaterSet(TS.TCNT, TS.PrescalerBits); } } \ No newline at end of file diff --git a/src/Internal/SquareWave.h b/src/Internal/SquareWave.h index e9cfd8b..153991e 100644 --- a/src/Internal/SquareWave.h +++ b/src/Internal/SquareWave.h @@ -4,40 +4,51 @@ namespace TimersOneForAll { namespace Internal { - template + template void SquareWaveToLow(); - template + template void SquareWaveToHigh() { - DoAfter>(); + DoAfter>(); Gifts::EfficientDigitalWrite(); } - template + template void SquareWaveToLow() { + Gifts::EfficientDigitalWrite(); if (InfiniteLr || --LR) - DoAfter>(); + DoAfter>(); + else if (DoneCallback) + DoneCallback(); + } + template + void OneShotSWDone() + { Gifts::EfficientDigitalWrite(); + if (DoneCallback) + DoneCallback(); } //这里要求RepeatTimes不能超过uint32_t上限的一半,故干脆直接限制为int32_t - template + template void InternalSW() { switch (RepeatTimes) { case 0: TIMSK = 0; + if (DoneCallback) + DoneCallback(); break; case 1: Gifts::EfficientDigitalWrite(); - DoAfter>(); + DoAfter>(); break; default: if (HighMilliseconds == LowMilliseconds) { constexpr TimerSetting TS = GetTimerSetting(TimerCode, HighMilliseconds); Gifts::EfficientDigitalWrite(); - SLRepeaterSet, (RepeatTimes < 0) ? -1 : RepeatTimes * 2 - 1>(); + SLRepeaterSet, (RepeatTimes < 0) ? -1 : RepeatTimes * 2 - 1, DoneCallback>(); } else { @@ -66,7 +77,11 @@ namespace TimersOneForAll { Gifts::EfficientDigitalWrite(); if (RepeatTimes > 0 && !--LR) + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } }; Gifts::EfficientDigitalWrite(); SetTCNT(0); @@ -74,7 +89,7 @@ namespace TimersOneForAll TIMSK = 6; } else - SquareWaveToHigh(); + SquareWaveToHigh(); } } } @@ -82,40 +97,44 @@ namespace TimersOneForAll static volatile uint16_t HM; template static volatile uint16_t LM; - template + template void SquareWaveToLow(); - template + template void SquareWaveToHigh() { - DoAfter>(HM); + DoAfter>(HM); Gifts::EfficientDigitalWrite(); } - template + template void SquareWaveToLow() { - if (InfiniteLr || --LR) - DoAfter>(LM); Gifts::EfficientDigitalWrite(); + if (InfiniteLr || --LR) + DoAfter>(LM); + else if (DoneCallback) + DoneCallback(); } //这里要求RepeatTimes不能超过uint32_t上限的一半,故干脆直接限制为int32_t - template + template void InternalSW(uint16_t HighMilliseconds, uint16_t LowMilliseconds) { switch (RepeatTimes) { case 0: TIMSK = 0; + if (DoneCallback) + DoneCallback(); break; case 1: Gifts::EfficientDigitalWrite(); - DoAfter>(HighMilliseconds); + DoAfter>(HighMilliseconds); break; default: if (HighMilliseconds == LowMilliseconds) { TimerSetting TS = GetTimerSetting(TimerCode, HighMilliseconds); Gifts::EfficientDigitalWrite(); - SLRepeaterSet, (RepeatTimes < 0) ? -1 : RepeatTimes * 2 - 1>(TS.TCNT, TS.PrescalerBits); + SLRepeaterSet, (RepeatTimes < 0) ? -1 : RepeatTimes * 2 - 1, DoneCallback>(TS.TCNT, TS.PrescalerBits); } else { @@ -144,7 +163,11 @@ namespace TimersOneForAll { Gifts::EfficientDigitalWrite(); if (RepeatTimes > 0 && !--LR) + { TIMSK = 0; + if (DoneCallback) + DoneCallback(); + } }; Gifts::EfficientDigitalWrite(); SetTCNT(0); @@ -155,34 +178,22 @@ namespace TimersOneForAll { HM = HighMilliseconds; LM = LowMilliseconds; - SquareWaveToHigh(); + SquareWaveToHigh(); } } } } } - //生成高低电平时长不一的方波,无限循环 - template + //生成循环数有限的方波。如不指定循环次数,默认无限循环 + template void SquareWave() { - Internal::InternalSW(); - } - //生成循环数有限的方波 - template - void SquareWave() - { - Internal::InternalSW(); - } - //生成高低电平时长不一的方波,无限循环 - template - void SquareWave(uint16_t HighMilliseconds, uint16_t LowMilliseconds) - { - Internal::InternalSW(HighMilliseconds, LowMilliseconds); + Internal::InternalSW(); } - //生成循环数有限的方波 - template + //生成循环数有限的方波。如不指定循环次数,默认无限循环 + template void SquareWave(uint16_t HighMilliseconds, uint16_t LowMilliseconds) { - Internal::InternalSW(HighMilliseconds, LowMilliseconds); + Internal::InternalSW(HighMilliseconds, LowMilliseconds); } } \ No newline at end of file