To create an Arduino Timer Interrupt, we need to decide two things, the time between Interrupts and the Timer we want to use. In the Video-Intro for RTM_TimerCalc, I chose 1000 milliseconds (which is 1 Second) and I selected Timer-1. After that, I generated some code and uploaded to a Mega 2560.
Since you may be using a Nano or Uno instead, remember those MCU cards can only use Timer1 and Timer2 -- while the 2560 has 5 Timers available.
Arduino Timer Interrupt with a 16-Bit Timer
For long Interval Interrupts like 1 Second, we want to use a 16 bit Timer. It can count to 65,535 where an 8 bit can only count to 255. That's a huge difference in Timing range. If you ask RTM_TimerCalc to give a 1-Second Interrupt using Timer-2, it will warn you the best you can hope for is ~32 milliseconds! That's way shorter than 1000 milliseconds. Here's an image of that calculation (click to enlarge).
As shown in the message window, there is no way an 8-bit Timer can deliver on 1000 milliseconds (at this clock frequency). But if we were looking for a shorter time (say 1, 2 4 or 8 milliseconds), then an 8-bit counter would work fine.
So that leaves us using a 16-bit counter like Timer-1 (found across all three MCU boards). When we ask for a 1000 millisecond Interrupt, it works just fine. See the next image.
Output Waveforms not Needed
So, lets take this a step further. The above images show code that includes waveform outputs. We don't really need waveforms for an Interval Interrupt. Worse still, I didn't check the "Include Interrupt" checkbox so the Timer interrupt code wasn't generated.
To fix these issues, I'll set the Output Compare Mode sliders to full left. That turns off the waveforms. Next Image shows what it looks like.
And I'll check the box for Including Interrupts and then re-calculate the code. See next Image...
As you can see, we have a lot less code generated. And we have no warnings in the Message Window. So, that should mean we're good to go.
Now we must copy the code from the Code Window and paste it into our IDE. We also need to have in mind some way to use our Interrupt. For this example, I just made the LED at Pin-13 flash on and off. Here's the resulting source code for this example (fleshed out and tested).
int volatile SecondsVar; ISR(TIMER1_OVF_vect){ SecondsVar++; } void setup() { //------------------------------------------------------- // generated by: RTM_TimerCalc -- RuntimeMicro.com // Timer1 Mode_10_16Bit_Phase_TOP_is_ICR TCCR1A = 0x02; // 0000 0010 TCCR1B = 0x10 | 4; // Prescale=256 ICR1 = 31250 - 0; // Set Overflow Interrupt Mask Bit TIMSK1 |= 1; // Interrupt --> ISR(TIMER1_OVF_vect){} //------------------------------------------------------- pinMode(13, OUTPUT); // LED pin } void loop() { digitalWrite(13, SecondsVar & 1); // LSB of SecondsVar drives LED ON and OFF }
The above code shows how -- using RTM_TimerCalc -- you can quickly create an Arduino Timer Interrupt.
Lee
Created: Jan 2, 2020 Updated: Jan 11, 2024 |