Timer ISR without clearing timer


I would like to use timer1 for multiple functions however; one of those is to trigger an ISR on a timer match. I'm still a little new to this but everything I've seen is CTC (Clear Timer on Compare Match). I just want the Compare Match to trigger an ISR and leave the timer alone. Is this possible?

Thank You in Advance,


The ISR will trigger at a specific value of the timer. You can set it to 9, for example. Usually this would clear the timer so it would start counting from zero and your ISR will be triggered every 10 counts.

You want to trigger your ISR every 10 but you want this to be 10, 20, 30, 40... because Timer1 is doing something else for you? You can change the value in the ISR - when it gets to 9, change your trigger to 19, then 29, then...

This is poor practice - your ISR will waste a lot of time changing this thing which doesn't need to be changed.

Does this unspecified-other-function need to be called every 100, for example? Then have your ISR keep a count of the times it's been triggered and do the other function after it counts to 10. This is actually how the millis() function works - it is running from a timer which overflows at 255 several times per millisecond and it keeps a count of the number of overflows before it increments the millisecond counter.

Ore use another timer, if the two functions aren't aligned as exact multiples.

Yes, just don't use CTC mode. There are other modes to use. Some count up and reset at the top value, some count up and then back down. If I knew more about what specifically you want to do I might could help you choose one.

I currently use timer1 to to read PPM (PPM is basically multiple PWM signals multiplexed on one wire). The micros() function only had 4µs resolution so I have to use the 16 bit timer1 with a scalar (divided by 8 ) to get .5µs resolution. This works great as long as I handle the overflow and I can read as many streams as I have pin ISRs on my board since I don't reset timer1. I wish to also use it to write a PPM stream, since it's my only 16 bit timer. I've read the data sheet but I don't seem to be able to find, or at least properly understand, a mode to match without resetting the timer, CTC being the default standard for matching a timer value to call an ISR. The only workaround I can seem to cook up is to reset the timer from zero back to the match value within the called ISR but this seems overly complex and grossly inefficient. Unfortunately, with all this stuff going on, extra steps affect the measured pulse time. Is there a way to use a timer match to call an ISR without resetting the timer back to zero?

Does that make sense?



unipres: I just want the Compare Match to trigger an ISR and leave the timer alone. Is this possible?

You can do this by putting the timer in normal mode and using one of the output compare registers to select the time of interrupt. For a periodic interrupt just keep adding the same number to the register each time the ISR is called. E.G., OCR1A += MY_INTERRUPT_PERIOD;

Or maybe I've misunderstood your question.

Is it really that simple?

I guess this is what happens when you try to attack advanced tasks with a high degree of inexperience.

So I could basically make my own micros() equivalent by taking say timer2 and

OCR2A += 16 if (OCR2A=255) OCR2A=0 counter++

and counter would increase in 1µs increments (assuming 16mHz clock) until "counter" overflowed for measuring time?

An interrupt every 1us is too fast. It takes more time to invoke, run and return from an ISR. Figure on something like 5us just to do something very simple. Plus, other interrupts in the system could delay yours from being invoked.

If all you want to do is create a more precise version of micros() then you only need to service an interrupt when the counter rolls over. If you used an 8-bit timer with a 0.5us step that would be once every 128us. That's probably going to be okay. Look at what they do in the Arduino timer0 ISR and micros() function and copy that, but adjust things for your timer and timer frequency. You can find that code in wiring.c.

unipres: if (OCR2A=255) OCR2A=0

You don't even need that line. The timer rolls over on its own. If you need to do math across the rollover, then just make sure you are using 8bit unsigned variables and it will handle itself.

ie. byte b = 245 + 15;

b will equal 4 now.