Stumped by _delay_ms()

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm getting stumped by the delay.h functions. I'm sure I'm shooting myself in the foot somehow, but can not seem to find the origin of the problem.
I have the following tiny piece of code:

/* delay_f_cpu.c */

#include 
#include 

void main () {
	DDRA =  0b00000001;

	while (1) {
		PORTA |= 0b00000001;	// impulse on
		_delay_ms(1);			// 1ms delay
		PORTA &= 0b11111110; 	// impulse off
		_delay_ms(10);
	}
}

I'm compiling it with avr-gcc 4.3.4 on linux with optimisation (-Os) and -DF_CPU:

avr-gcc -Wall -Os -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -mmcu=attiny861 -DF_CPU=8000000UL -MMD -MP -MF"delay_f_cpu.d" -MT"delay_f_cpu.d" -c -o"delay_f_cpu.o" "../delay_f_cpu.c"

Then I run it on a tiny861 using the internal 8Mhz clock.

I expect to get an 1ms impulse every 11ms. But I get a 250us impulse every 2700us. My delay functions are running a factor of four too fast. If I define F_CPU to be 32000000, then the impulses are right on time. I'm using a scope to measure the impulses, so my accuracy is +/- 10%, but a factor of four...

Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is one version of avr-libc out there with a broken delay function, off by a factor of four. Get an older or newer version of the lib.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see, this looks like exactly my symptom.

How can I check which version I have ?

Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your program simulates just fine.
Personally, I would set the CLKPR register so that you know what speed the AVR core is running at.

Bear in mind that there are PLL options and a Fast Peripheral clock.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The broken version is the most recent avr-libc 1.7.0

There are patches.

John

If all else fails, read the instructions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

markus_b wrote:
How can I check which version I have ?
avr/version.h

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

I see I've got the broken version.

This look like the bug description to me.

Quote:
bug #30363: _delay_xx() functions in are broken

I'll patch it then. :-)

Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I patched it, recompiled and reinstalled avr-libc, recompiled and reflashed my testcase and it works perfectly now !

Thanks guys :-)

Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

WHERE do we find this ?!

thanks

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indianajones11 wrote:

#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

WHERE do we find this ?!

thanks

My path looks like this..

"C:\WinAVR-20100110\avr\include\avr"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indianajones11 wrote:

#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

WHERE do we find this ?!

thanks


https://www.avrfreaks.net/index.p...

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indianajones11 wrote:

#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

WHERE do we find this ?!

thanks

In my installation it is here:

Quote:
markus@T60:~$ grep -r "__AVR_LIBC_VERSION_STRING__" /usr/local
/usr/local/avr/avr/include/avr/version.h:#define __AVR_LIBC_VERSION_STRING__ "1.7.0"

Markus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,
I'm still figuring out the mechanics of things AVR, and this forum.

I am using a Butterfly, which is meant to be running on an internal oscillator at 8MHz. Trying to up load a simple "blink" program results in this 4x delay period. I don't get any compile errors or warnings.

// Blinky.c
#include 
#include 

//#define F_CPU 800000	/* CPU clock in Hertz */

int main(void)
{
	// Set port D for output
	DDRD = 0xFF;
		while(1)
		{
			
			PORTD=1;
			_delay_us(50);
			PORTD=0;
			_delay_us(200);
		}
}

I note that I have version 1.6.7 (from WinAVR-20100110-install.exe) so uninstalled that and installed WinAVR-20090313.exe which gave me version 1.6.6 (as per version.h) but still get this 4x delay period issue.

Is there something else I have overlooked?
Regards
Chris

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I am using a Butterfly, which is meant to be running on an internal oscillator at 8MHz.
If you mean the software that came with the Butterfly, it runs at 2MHz, not 8MHz.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
I am using a Butterfly, which is meant to be running on an internal oscillator at 8MHz.
If you mean the software that came with the Butterfly, it runs at 2MHz, not 8MHz.

Thanks for confirming that Koshchi. I did look at the output on a scope and, doing the math, figured that it would have to be running at 2MHz, but it did not make sense to me. Of course, if I was running it off the battery, 2MHz would make sense.

Do you (or anybody else) know where I can get a suitable boot loader for the butterfly, to run at full speed?

Regards
Chris

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you (or anybody else) know where I can get a suitable boot loader for the butterfly, to run at full speed?

I may have found what I am looking for here
http://gandalf.arubi.uni-kl.de/avr_projects/
I think I just need to change the CLKPS<3:0> Clock prescaler select bits. I will experiment tomorrow. Regards, Chris

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not just change the CKSEL fuses to enable the 169's 8MHz RC rather than the 2MHz one? You will need to pull the Butterfly bootloader source and also modify its calibration routine to take account of this. But not many other bootloaders even HAVE a calibration routine so it's likely the best starting point.