AVR GCC ASM

Feb 16, 2006 9 Replies

Hello,



Can someone provide a way to replace the following "nop\n\t" statements with a loop? I apologize in advance for not spending the time to try and figure this out, but I must admit that I find GCC ASM somewhat difficult. I would appreciate any help.



Sam



static __inline__ void _delay_20(uint16_t __count) { __asm__ volatile ( "1: sbiw %0,1" "\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" "brne 1b" : "=w" (__count) : "0" (__count) ); }



I'd skip that mess altogether and use one of the routines in avr/delay.h.

Regards, -=Dave

Change is inevitable, progress is not.

This snippet of code appears to be crafted to wait a moderately specific number of CPU cycles. If you recode it in C, you're going to lose control; things are going to shift around when you change compiler versions or optimizer switches.

When I want a quick and dirty delay and can't be bothered learning how to do things properly for the compiler/runtime library/CPU in question, I usually do something like this:

#define FILTHYDELAYCODE(n) { uint8_t i,j; for (i=0;i

Hmmm. I was going to recommend some ATMega16 code I did the hard way, for the artinterfacedevice project on sourceforge. I guess I'd better look at delay.h

Thanks, Mel.

Try it with GCC - it disappears.

The trick with GCC is ether to use a volatile variable inside a loop, or to use a non-null assembly statement in the loop.

Tauno Voipio tauno voipio (at) iki fi

The trick with GCC used to be that if you want an empty delay loop, you just have to *write* exactly that: an empty delay loop. The reasoning was that if you wrote actual code and GCC detected it could optimize it away, it did. But if the loop was empty to begin with, it guessed that that's what you wanted, and left it alone. See

info gcc Trouble "non-bugs"

Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.

Could you give me an example? I have been banging my head against inline assembly all day and getting no where. All I really want is a delay routine for 10,000 instruction cycles. I would really appreciate any help.

Thanks! Sam

The most important hint you need is that there's no point doing that in inline assembly. Either use a separate, real assembly source file with that function in it, or re-think the entire idea of wasting that many CPU cycles, when you almost certainly could do something useful with them instead, and have a timer take care of counting time for you

--- since that is what you have timers for.

Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.

If I were you I would scrap that all together and implement the delay using a timer interrupt.

Well, this seems to work pretty well to delay for microseconds with a known clock rate. I'm not completely sure that it's accurate right down to the cycle. It may not have been tested yet with milliseconds...

(attached to avoid line-wrap in mail software)

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required