This repository has been archived by the owner on Jan 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimerInterruptTest.ino
124 lines (97 loc) · 4.64 KB
/
TimerInterruptTest.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/****************************************************************************************************************************
TimerInterruptTest.ino
For Arduino AVR ATtiny-based boards (ATtiny3217, etc.) using megaTinyCore
Written by Khoi Hoang
Built by Khoi Hoang https://github.com/khoih-prog/ATtiny_TimerInterrupt
Licensed under MIT license
Now with we can use these new 16 ISR-based timers, while consuming only 1 hwarware Timer.
Their independently-selected, maximum interval is practically unlimited (limited only by unsigned long miliseconds)
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
*****************************************************************************************************************************/
// Important Note: To use drag-and-drop into CURIOSITY virtual drive if you can program via Arduino IDE
// For example, check https://ww1.microchip.com/downloads/en/DeviceDoc/40002193A.pdf
#if !( defined(MEGATINYCORE) )
#error This is designed only for MEGATINYCORE megaAVR board! Please check your Tools->Board setting
#endif
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG 0
#define _TIMERINTERRUPT_LOGLEVEL_ 0
// Select USING_FULL_CLOCK == true for 20/16MHz to Timer TCBx => shorter timer, but better accuracy
// Select USING_HALF_CLOCK == true for 10/ 8MHz to Timer TCBx => shorter timer, but better accuracy
// Select USING_250KHZ == true for 250KHz to Timer TCBx => longer timer, but worse accuracy
// Not select for default 250KHz to Timer TCBx => longer timer, but worse accuracy
#define USING_FULL_CLOCK true
#define USING_HALF_CLOCK false
#define USING_250KHZ false // Not supported now
// Try to use RTC, TCA0 or TCD0 for millis()
#define USE_TIMER_0 true // Check if used by millis(), Servo or tone()
#define USE_TIMER_1 false // Check if used by millis(), Servo or tone()
#if USE_TIMER_0
#define CurrentTimer ITimer0
#elif USE_TIMER_1
#define CurrentTimer ITimer1
#else
#error You must select one Timer
#endif
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ATtiny_TimerInterrupt.h"
#ifdef LED_BUILTIN
#undef LED_BUILTIN
// To modify according to your board
// For Curiosity Nano ATtiny3217 => PIN_PA3
#if defined(ARDUINO_AVR_CuriosityNano3217)
#define LED_BUILTIN PIN_PA3
#else
// standard Arduino pin 13
#define LED_BUILTIN PIN_PA3
#endif
#endif
// standard Serial
#define SerialDebug Serial
void TimerHandler1(unsigned int outputPin = LED_BUILTIN)
{
static bool toggle = false;
#if (TIMER_INTERRUPT_DEBUG > 1)
SerialDebug.print("ITimer called, millis() = "); SerialDebug.println(millis());
#endif
//timer interrupt toggles pin LED_BUILTIN
digitalWrite(outputPin, toggle);
toggle = !toggle;
}
unsigned int outputPin1 = LED_BUILTIN;
#define TIMER1_INTERVAL_MS 5000
#define TIMER1_FREQUENCY (float) (1000.0f / TIMER1_INTERVAL_MS)
#define TIMER1_DURATION_MS 0 //(10 * TIMER1_INTERVAL_MS)
#define ADJUST_FACTOR ( (float) 0.99850 )
void setup()
{
SerialDebug.begin(115200);
while (!SerialDebug && millis() < 5000);
pinMode(outputPin1, OUTPUT);
SerialDebug.print(F("\nStarting TimerInterruptTest on ")); SerialDebug.println(BOARD_NAME);
SerialDebug.println(AT_TINY_TIMER_INTERRUPT_VERSION);
SerialDebug.print(F("CPU Frequency = ")); SerialDebug.print(F_CPU / 1000000); SerialDebug.println(F(" MHz"));
SerialDebug.print(F("TCB Clock Frequency = "));
#if USING_FULL_CLOCK
SerialDebug.println(F("Full clock (20/16MHz, etc) for highest accuracy"));
#elif USING_HALF_CLOCK
SerialDebug.println(F("Half clock (10/8MHz, etc.) for high accuracy"));
#else
SerialDebug.println(F("250KHz for lower accuracy but longer time"));
#endif
SerialDebug.print(F("CPU ADJUST_FACTOR = ")); SerialDebug.println(ADJUST_FACTOR);
CurrentTimer.init();
if (CurrentTimer.attachInterruptInterval(TIMER1_INTERVAL_MS * ADJUST_FACTOR, TimerHandler1, outputPin1, TIMER1_DURATION_MS))
{
SerialDebug.print(F("Starting ITimer OK, millis() = ")); SerialDebug.println(millis());
}
else
SerialDebug.println(F("Can't set ITimer. Select another freq. or timer"));
}
void loop()
{
}