Embedded design tip: timer interrupt "dirty trick" speeds up data acquisition - Embedded.com

Embedded design tip: timer interrupt “dirty trick” speeds up data acquisition

Fast digital data sampling with 8 bit microcontrollers (e.g. in logicanalyzers) typically use a tight loop (Listing1 below ) to do the following:

Read data from input port
Store data in buffer via a pointer
(Auto-) increment pointer by one
Check pointer for end-of-buffer
Loop if not at end

Listing1

This takes six processor cycles on an AVR processor [1] [2] . So with a processor clockof six MHz the sample rate is 1 MSamples/sec.

Except for the comparison of the end condition, all instructions areviable and no optimization is possible. But the comparison seemssomehow wasted because its only use is to terminate the loop. But itmust be executed every iteration.

Using and comparing a 16 bit pointer to sample more than 256 bytesatbest makes it even worse (Listing 2below ). Now you have two “unnecessary” compare-instructions:

Listing2

If there were is a different way to end the loop, thecompare- instruction(s) could be eliminated with the result that thespeed would only take up fiveprocessor cycles (main_loop in Listing3 below ). This woult yield a sampling rate of 1.2M samples inthefirst example: a gain of 20% in speed (or a gain of 40% when using 16bit compares):

Listing3

To implement this scheme, first start a start a timer just beforethe loop starts and then have the timer trigger an interrupt after acertain amount of processor cycles. This won't help much, because afterthe interrupt handler finishes, we are back in the endless loop.

But, by using a “dirtytrick” (typically used by PC “bufferoverflow”-viruses) modifying the return address of the interrupthandler to point behind the loop, the goal is achieved: the loop isterminated.

In most cases, this is easy because the return address for theinterrupt is pushed on the stack, which is changeable with some dataoperations (see Listing 3 above ).Of course, the stack layout must be set for manipulation.

The calculation of the timer values must be accurate if a fixednumber of samples are required. If the exact number of samples isirrelevant to a certain amount (a few bytes more or less), these timingvalues mandate only the maximum buffer size be used (we don't want tohave a buffer overflow !). The last sample stored can be determined bythe value of the pointer (Z register) in either the interrupt handleror after the loop.

Note [1] :The examples wok only on AVR processors not having a hardware stack(e.g. ATtiny15), because there is no stack pointer and the stack cannotbe manipulated., in detail: the push and pop instructions are notavailable.

Note [2] : Although all examples are shown for theATMEL AVR-processors (ATtiny, ATMega,AT8xxx), the method is applicableto other processor architectures too.

All the necessary code forimplementing this hint is available at AndreasGruenCode.zipor by going to the Embedded.comDownload Code Archive

Andreas Gruenhas been involved inhands-on electronics design since the age of 12. After getting a MSdegree in physics in Germany and stints at Rice University in Houston,Texas and Utrecht University in Holland, he spent several yearsteaching – and doing – programming in C and high level database design.Since 2004 he has been CTO at Holistic-Net, involved in productdevelopment and project managment. For fun he goes back to his roots,programming microcontrollers.

“Maybethe lack of perfection inplaying guitar, piano and poker led me to embedded controllers,” hesaid. “They're somewhat more predictable. I have gained a lot ofexperience in programming (multithread, multiprocessor, HW devices)over time, and programming microcontrollers was a kind of back to theroots. After years of 'keyboarding' I needed to take the solder-ironback into my hands.” He can be contacted at andreas@gruenfrosch.de.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.