long delay in AVR GCC ???

Started by sam...@machinescience.org February 16, 2006
I would very much appreciate if anyone could provide code for a
reliable 10,000 instruction cycle delay routine for AVR GCC (in either
asm or C). I have been banging my head all day against GCC inline
assembly and getting no where! I find it to be an incredibly criptic
language with little documentation. I would really, really appreciate
any help.

Thanks!
Sam

sam@machinescience.org wrote:
> I would very much appreciate if anyone could provide code for a > reliable 10,000 instruction cycle delay routine for AVR GCC (in either > asm or C). I have been banging my head all day against GCC inline > assembly and getting no where! I find it to be an incredibly criptic > language with little documentation. I would really, really appreciate > any help. > > Thanks! > Sam
Why don't you use timers? Most AVRs have at least one.
On 16 Feb 2006 12:53:28 -0800 in comp.arch.embedded,
"sam@machinescience.org" <sam@machinescience.org> wrote:

>I would very much appreciate if anyone could provide code for a >reliable 10,000 instruction cycle delay routine for AVR GCC (in either >asm or C). I have been banging my head all day against GCC inline >assembly and getting no where! I find it to be an incredibly criptic >language with little documentation. I would really, really appreciate >any help.
There's lots of documentation. Where are you looking? If I wanted to write a delay loop, in avr-gcc, I'd look for something in the library with the string 'delay' in it. Y'know, like delay.h? Googling "avr libc delay" (without the quotes) gives http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html as the third hit. _delay_loop_2(n) delays 4*n machine cycles. Something like #include <util/delay.h> ... _delay_loop_2(2500); should work nicely. If you want to delay for a period of time measured in microseconds rather than machine cycles, and you have a 1MHz clock, you can use #define F_CPU 1000000 #include <util/delay.h> ... delay_us(10000) That way you can change your oscillator but keep your delay loops the same length by updating the value for F_CPU and recompiling. In my makefile, I would set F_CPU on the compiler command line in the makefile using -D. Note: older versions of the library have this in <avr/delay.h> Regards, -Úve -- Change is inevitable, progress is not.
In article <1140123997.804150.182790@g44g2000cwa.googlegroups.com>,
 "linnix" <me@linnix.info-for.us> wrote:

> Why don't you use timers? Most AVRs have at least one.
Why do anything simple way when one can make it complex and wonderful? I think some people simply have a problem thinking outside of the box. That things like interrupts and hardware timers are exotic, frightening, and best avoided, no matter that they are already there, paid for, whether they are used or not.
On Thu, 16 Feb 2006 20:59:43 -0600, David Kelly <n4hhe@yahoo.com>
wrote:

>In article <1140123997.804150.182790@g44g2000cwa.googlegroups.com>, > "linnix" <me@linnix.info-for.us> wrote: > >> Why don't you use timers? Most AVRs have at least one. > >Why do anything simple way when one can make it complex and wonderful? > >I think some people simply have a problem thinking outside of the box. >That things like interrupts and hardware timers are exotic, frightening, >and best avoided, no matter that they are already there, paid for, >whether they are used or not.
The nop-loop style delays are going to be reliable only as long as there are no interrupt service routines firing during the delay period. If the delay is long and the interrupts are badly predictable (say input change interrupts), the interrupt service routines will consume a considerable and variable amount of the cycles. Disabling all interrupts may be a solution in some cases, however, this might not be an option if long delays are needed. If the processor contains a true clock cycle counter, like the TSC on Pentiums, it should be easy to monitor it until the required count has been reached regardless of interrupts. Also any free running counter driven from a reliable source (say the UART clock) can be used. In these cases the wakeup can be delayed by only one interrupt service routine time. Using a clock interrupt to count the time is problematic due to the lower granulaty, since the interrupt service routine interrupt rate must be quite low to allow for the execution of the clock interrupt service routine. One reasonable approach would be to use the clock interrupt just prior to the required wake up time and do the last step with a nop-loop, since the likelihood for multiple other interrupts would be quite small during the nop-loop. Paul
On Thu, 16 Feb 2006 20:59:43 -0600, David Kelly <n4hhe@yahoo.com>
wrote:

>In article <1140123997.804150.182790@g44g2000cwa.googlegroups.com>, > "linnix" <me@linnix.info-for.us> wrote: > >> Why don't you use timers? Most AVRs have at least one. > >Why do anything simple way when one can make it complex and wonderful? > >I think some people simply have a problem thinking outside of the box. >That things like interrupts and hardware timers are exotic, frightening, >and best avoided, no matter that they are already there, paid for, >whether they are used or not.
The nop-loop style delays are going to be reliable only as long as there are no interrupt service routines firing during the delay period. If the delay is long and the interrupts are badly predictable (say input change interrupts), the interrupt service routines will consume a considerable and variable amount of the cycles. Disabling all interrupts may be a solution in some cases, however, this might not be an option if long delays are needed. If the processor contains a true clock cycle counter, like the TSC on Pentiums, it should be easy to monitor it until the required count has been reached regardless of interrupts. Also any free running counter driven from a reliable source (say the UART clock) can be used. In these cases the wakeup can be delayed by only one interrupt service routine time. Using a clock interrupt to count the time is problematic due to the lower granulaty, since the interrupt service routine interrupt rate must be quite low to allow for the execution of the clock interrupt service routine. One reasonable approach would be to use the clock interrupt just prior to the required wake up time and do the last step with a nop-loop, since the likelihood for multiple other interrupts would be quite small during the nop-loop. Paul
In article <1140123997.804150.182790@g44g2000cwa.googlegroups.com>,
 "linnix" <me@linnix.info-for.us> wrote:

> Why don't you use timers? Most AVRs have at least one.
Why do anything simple way when one can make it complex and wonderful? I think some people simply have a problem thinking outside of the box. That things like interrupts and hardware timers are exotic, frightening, and best avoided, no matter that they are already there, paid for, whether they are used or not.
On 16 Feb 2006 12:53:28 -0800 in comp.arch.embedded,
"sam@machinescience.org" <sam@machinescience.org> wrote:

>I would very much appreciate if anyone could provide code for a >reliable 10,000 instruction cycle delay routine for AVR GCC (in either >asm or C). I have been banging my head all day against GCC inline >assembly and getting no where! I find it to be an incredibly criptic >language with little documentation. I would really, really appreciate >any help.
There's lots of documentation. Where are you looking? If I wanted to write a delay loop, in avr-gcc, I'd look for something in the library with the string 'delay' in it. Y'know, like delay.h? Googling "avr libc delay" (without the quotes) gives http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html as the third hit. _delay_loop_2(n) delays 4*n machine cycles. Something like #include <util/delay.h> ... _delay_loop_2(2500); should work nicely. If you want to delay for a period of time measured in microseconds rather than machine cycles, and you have a 1MHz clock, you can use #define F_CPU 1000000 #include <util/delay.h> ... delay_us(10000) That way you can change your oscillator but keep your delay loops the same length by updating the value for F_CPU and recompiling. In my makefile, I would set F_CPU on the compiler command line in the makefile using -D. Note: older versions of the library have this in <avr/delay.h> Regards, -Úve -- Change is inevitable, progress is not.
sam@machinescience.org wrote:
> I would very much appreciate if anyone could provide code for a > reliable 10,000 instruction cycle delay routine for AVR GCC (in either > asm or C). I have been banging my head all day against GCC inline > assembly and getting no where! I find it to be an incredibly criptic > language with little documentation. I would really, really appreciate > any help. > > Thanks! > Sam
Why don't you use timers? Most AVRs have at least one.
I would very much appreciate if anyone could provide code for a
reliable 10,000 instruction cycle delay routine for AVR GCC (in either
asm or C). I have been banging my head all day against GCC inline
assembly and getting no where! I find it to be an incredibly criptic
language with little documentation. I would really, really appreciate
any help.

Thanks!
Sam