Create an Arduino Timer Interrupt Fast

1 post / 0 new
Runtime Micro's picture
Runtime Micro
Offline
Joined: 07/24/2016 - 9:18am
Create an Arduino Timer Interrupt Fast

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).

settiing up an Arduino Timer Interrupt with RTM_TimerCalc application.

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.

Image shows Timer-1 Interval Interrupt setup but with extra code.

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.

Image shows Output Compare Modes set to OFF.

And I'll check the box for Including Interrupts and then re-calculate the code. See next Image...

Image shows proper setup for 1000 millisecond Arduino Timed Interrupt.

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