Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

AVR Timer Interrupt Jitter

Status
Not open for further replies.

cgchas

Member level 3
Joined
Jul 19, 2011
Messages
56
Helped
2
Reputation
8
Reaction score
4
Trophy points
1,288
Activity points
2,001
I am looking for options for eliminating interrupt jitter on an 8-bit AVR such as the ATmega328p.

I am aware that if an interrupt occurs during execution of a multi-cycle instruction, this instruction is completed before the interrupt is served. This comes from 7.7.1 Interrupt Response Time, of the ATmega328p datasheet. Such is my case.

What are some good methods for knowing the CPU state before the interrupt triggers?

Various Google searches have yielded results suggesting sleeping the CPU from the main loop before the interrupt triggers. This is ok if the added wakeup latency is acceptable and if the AVR can be dedicated to the interrupt this way. But is there any other way?

For example, given a very small main loop, but not sleeping the CPU, is it possible to determine from the ISR, after the interrupt servicing has begun, what the last executed instruction was from the main loop or perhaps the last location of the program counter, before the jump? If so, this would allow for a deterministic timing correction, but I am not sure if it is possible.

Thanks in advance for any assistance.
 

You didn't tell what you exactly want to achieve.

With most microprocessors, it's possible to resync code execution insiside the timer interrupt procedure to a defined delta time after the trigger event, e.g. by waiting for a specific timer count. I presume it's also possible for AVR.
 

You didn't tell what you exactly want to achieve.

With most microprocessors, it's possible to resync code execution insiside the timer interrupt procedure to a defined delta time after the trigger event, e.g. by waiting for a specific timer count. I presume it's also possible for AVR.

What I want to achieve exactly is removal of clock-resolution jitter between an interrupt and the main loop execution of an 8-bit AVR.

It seems that you are suggesting a fix for latency which is not what I am referring to. A defined or fixed delta would not do it because on AVRs, the interrupt does not get serviced at a fixed time given that the CPU could be in the middle of a multi-cycle instruction. I am looking for a way to deterministically eliminate jitter by compensating dynamically in the ISR if I can find a way to know what state the CPU was in before the ISR gets called. There is probably more than one way to do that, but I do not as of yet know any.

Consider for example a pulse train of some arbitrary low value in hertz, even with a main loop that essentially does nothing, i.e. while(1){}, any interrupt that attempts to measure or detect that pulse in any way will trigger very close to the rate of the pulse given some latency offset due to the overhead of the interrupt itself, but additionally will often be 2-4 cycles off due to the possibility that the jump instruction behind the while loop is 2 clocks in length. That jump must complete before the interrupt gets serviced. Subsequent interrupts may happen at the same time or perhaps after a single clock instruction which for that case means the ISR executes .05 uSec sooner on a 20MHz clock than it did last time.

If there was a way to store in a table all of the addresses of all the instructions of a main loop and know which address the program counter was at just prior to the ISR execution I could easily determine how many clocks needed to be compensated (NOP'd) for.
 

YES. I think I get it.
Yes, the entire problem is the multi-cycle instructions before the interrupt. What "FvM" was trying to say is, when you enter your interrupt, first run some code that looks like "while(TCNT0<15) {nop;}". How exactly to accomplish this I don't know, because this while loop isn't one cycle long, but thats the concept. maybe some assembly code. This way, when you enter your ISR at TCNT0 clock cycle 10,11,or 12, you can always wait for 15, then run the rest of the ISR.

I had another idea. I am sending data to a DAC in a timer interrupt and am having the same jitter problem. My plan is to use the interrupt to load all the data into the dac, then use the hardware PWM pin to toggle the DAC latch pin. This way the jittery ISR doesnt even matter. For example, Timer overflows, ISR runs, load two bytes into DAC, set the DAC latch pin high, then at the next timer overflow, let the AVR hardware clear the output compare pin, pulling the DAC latch low. Then in the ISR again, setup the next sample. Maybe that helps.

And thank you for asking this question. I thought I was going insane that my timers were glitchy.
 

I agree that using hardware instead of software controlled timing (your second approach) is usually the better way to generate processor actions accurate to a crystal cycle. In so far, all software based synchronizing means are only second choice.

Secondly you are right that polling the timer in a simple loop can't achieve accurate synchronization. A more complex scheme is required, e.g. combining different delay amounts and possibly reading the timer more than once.

Finally a comment on the table idea sketched in post #3. If processor was interrupted during a multi-cycle instruction, you still don't know when the interrupt exactly occured. Thus I fear, the method doesn't help even in this simple case. More generally, you'll often need short interrupt locks to assure data consistency.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top