Why is _delay_ms_ behave unpredictably ?

Go To Last Post
81 posts / 0 new

Pages

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

It would be much easier to understand those things, if the compiler could generate a full list of definitions and equates. 

In assembly, if you state #LIST, it will create a list file with everything, so you can just eyeball it and find possible problems or discrepancies from what you think must be right.

Why hide those things form the user? what is the intention?  

Wagner Lipnharski
Orlando Florida USA

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

GCC has almost exactly that with - fverbose-asm passed to the compiler if you elect to keep the .s files.

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

clawson wrote:
One of my early thoughts was "Symbols" in project properties making a -DF_CPU=nnnnUL that would over-ride any subsequent #define in .h/.c files.

I'd wager that source files will override "command line defines".  Last one wins, right?  At least it does in CodeVision.  Or are you saying that every line such as #define is examined after it is carried out to see whether the result has a global override?  Not the way I'd write my compiler.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Last one wins is just a tradition.

As it only applies to situations that are supposed to not happen,

compilers are allowed to ignore the tradition.

I know of none that do.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

theusch wrote:
I'd wager that source files will override "command line defines".  Last one wins, right? 
Good question. I suppose the question is really "when an already defined warning is given does the prepro then use the existsing def or the new one"

 

So under "Symbols" I entered

FOO=3

then I built:

#include <avr/io.h>

#define FOO 5

int main(void)
{
	PORTD = FOO;
}

and the .i file is:

# 7 ".././main.c" 3
(*(volatile uint8_t *)((0x0B) + 0x20)) 
# 7 ".././main.c"
      = 5;

So you are right - the last one over-rides. Bang goes that theory then!

Last Edited: Thu. Apr 11, 2019 - 09:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If your fuses are set in such a way so as to invoke the 1MHz internal clock of avr then F_CPU will have no effect for any integer greater than 1Mhz. 

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

SufyanRaza26 wrote:
then F_CPU will have no effect f
I fear you misunderstand. Sure F_CPU cannot change the speed of the CPU but it sure can affect the number of delaying opcodes used when various forms of _delay_us()/_delay_ms() are then used.

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

To be explicit: F_CPU is just a symbol that by convention is usually

#define-d or command line-define-d to be the CPU frequency in Hertz.

Lying is allowed, but is rarely wise.

Accidental mismatches have the same effects as lying.

The usual accidental mismatch involves the DIV8 fuse.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

_delay_ms is an actual function.

It is defined the first time its header file

is #include-d or command line-included.

Subsequent inclusions do not matter,

hence subsequent #define-s of F_CPU do not matter.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

skeeve wrote:

Subsequent inclusions do not matter,

hence subsequent #define-s of F_CPU do not matter.

OP has become quiet.  Let's concentrate on solving the dozen-line program, with no redefinition.

 

My money is that the .HEX being loaded, "identical" no matter the F_CPU value, isn't the one produced by the build of the source file.

 

Checking that, and .LSS, and similar should be straightforward for OP given all the effort already to-date.  Is OP really using VisualStudio and not AtmelStudio?  It seems that we may never know.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
My money is that the .HEX being loaded, "identical" no matter the F_CPU value, isn't the one produced by the build of the source file.

 

That's my bet also - - -  why ?

Been there ; done very similar in forgetting to actually flash program the new hex  ; and not just once either.

 

OP probably dying of embarrassment at the post count his "mistake" has generated.

 

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

From the gcc documentation:

 

3.8 Undefining and Redefining Macros

If a macro ceases to be useful, it may be undefined with the ‘#undef’ directive. ‘#undef’ takes a single argument, the name of the macro to undefine. You use the bare macro name, even if the macro is function-like. It is an error if anything appears on the line after the macro name. ‘#undef’ has no effect if the name is not a macro.

#define FOO 4
x = FOO;        → x = 4;
#undef FOO
x = FOO;        → x = FOO;

Once a macro has been undefined, that identifier may be redefined as a macro by a subsequent ‘#define’ directive. The new definition need not have any resemblance to the old definition.

However, if an identifier which is currently a macro is redefined, then the new definition must be effectively the same as the old one. Two macro definitions are effectively the same if:

  • Both are the same type of macro (object- or function-like).
  • All the tokens of the replacement list are the same.
  • If there are any parameters, they are the same.
  • Whitespace appears in the same places in both. It need not be exactly the same amount of whitespace, though. Remember that comments count as whitespace.

These definitions are effectively the same:

#define FOUR (2 + 2)
#define FOUR         (2    +    2)
#define FOUR (2 /* two */ + 2)

but these are not:

#define FOUR (2 + 2)
#define FOUR ( 2+2 )
#define FOUR (2 * 2)
#define FOUR(score,and,seven,years,ago) (2 + 2)

If a macro is redefined with a definition that is not effectively the same as the old one, the preprocessor issues a warning and changes the macro to use the new definition. If the new definition is effectively the same, the redefinition is silently ignored. This allows, for instance, two different headers to define a common macro. The preprocessor will only complain if the definitions do not match.

 So, why not #undef F_CPU

 

then #define it to your desired value?

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

ka7ehk wrote:

So, why not #undef F_CPU

 

then #define it to your desired value?

If it was wrong and _delay_ms was already defined,

changing F_CPU will not help.

OP probably needs to change the command line,

presumably with IDE options.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

Correct.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Fri. Apr 12, 2019 - 05:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On top of all the calls to see .lss etc, I'd sure like to see these:

Blink8MHz.ino.with_bootloader.hex	 8,183 	 identical 	hex
Blink8MHz.with_bootloader.hex	         8,183 	 identical 	hex
Blink8MHz.hex	                         283 	 identical 	hex
Blink8MHz.ino.hex	                 283 	 identical 	hex

OP, attach or copy/paste them here, please.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Yes you are right!! Thanks for correcting me :) 

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

ka7ehk wrote:

Project > (yourprojectname) properties > AVR/GNU common > Output files > .lss (generate lss file)

 

Then after building, you find the file in Solution Explorer > Output files > (yourprojectname).lss

 

Jim

Thanks for the instructions but it aint working for me, any idea ?

I rebuilt the short code but still no LSS file in the release folder ?

LSS menu selection

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

Did you look in Solution Explorer > Output files > (yourprojectname).lss  ??

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Look in the debug folder.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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


js wrote:

Look in the debug folder.

Picture shows he is building "Release" so I would expect to find LSS in <project>\Release directory. If I build a test project I see something like:

 

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

Again, a wild guess:  Can't find .LSS, and changed builds have no effect:  The output isn't where you think it is.  The build log should give full file names?  Do a full build, and check the date stamps on the output files? 

 

Sometimes a brute-force search of the hard drive is enlightening; e.g., "find all .LSS and .HEX files from today".

 

Could the directory target be on a different e.g. network drive?   Perhaps that secure drive is W.O.M.?

http://repeater-builder.com/molo...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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


The two ways I use to be sure where files are built (both in AS7 and Visual Studio are both shown in this picture:

 

 

Both start with "Output Files". Either:

 

1) double-click a file listed in Output Files so it is loaded into the editor then hover the mouse over the tab for that file. As seen in "1" above then the hover tooltip shows you where the file is actually located. In my case this is D:\test\test\Release\test.lss

 

2) Alternatively (possibly the one I prefer) use "View-Properties Window" (Alt-enter) to make sure the Properties window is open onscreen somewhere then simply highlight the file (test.lss in this case under Output Files) and "Properties" will be updated to show you the properties of that file. As shown in "2" in the picture this shows the file is called test.lss and is located in D:\test\test\Release\

 

You can do the same for the actual .HEX file too:

 

 

Several additional cool things going on here (apart from the fact that either method confirms D:\test\test\Release as the location) and that is (a) AS7 does a very nice job of displaying hex file contents and (b) (never noticed before) there's additional data in "Properties" to show the binary size represented by the Hex contents - which is nice.

 

Anyway like both Lee and I have said above this whole thread looks an awful lot like you are programming a different file to the one you are building. So use either of the above to identify exactly where the .HEX file is then go to your programming system and make sure that the .hex file listed there is the same thing. Strong chance it isn't.

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

I finally decided to Clean Install AS7, no Visual-Micro no Arduino IDE.

I'M up and running. I can program my ATtiny85 with my simple LED flash code.

An, Yes, the F_CPU 1000000 or F_CPU 8000000 make a difference in the chip behavior, just as it should.

Has the chip is Hard Burned for a default frequency of 1MHz, telling the code that F_CPU is 8MHz will make the LED flash 8 times slower.

Case closed. The problem is embedded in the Arduino layer somehow. Where is the problem is the subject for a whole new research project which is not on my priority list for now.

Thanks to all for your technical support.

#define F_CPU 8000000   // or F_CPU 1000000 Makes a big difference
#include <avr/io.h>     // In AS7 environment
#include <util/delay.h>

int main(void) {
    DDRB |= (1 << PB0);	//	PB0 is now Output

    while (1) {
        PORTB |= (1 << PB0);
        _delay_ms(200);

        PORTB &= ~(1 << PB0);
        _delay_ms(200);
    }
    return 0;
}

 

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

FredCailloux wrote:
The problem is embedded in the Arduino layer somehow.

I wouldn't think so, from the evidence you DID show.

 

Why the resistance, after the many back-and-forths on this issue, to post the log of the build?  To post the .LSS output file contents?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Lee, he's using Visual Studio+Visual Micro, not AS7, sounds like it doesn't do LSS by default.

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

clawson wrote:
he's using Visual Studio+Visual Micro, not AS7

But in #68 the image shows Atmel Studio in the title bar.  A red herring?  The app icon upper left of the title bar tells the story?

 

Even with the "related" installation, wouldn't the build log be shown in >>some<< pane?

 

I could envision how the named Arduino culprit might put stuff in a different spot.  But we never saw Output Files in a navigator pane?  Nor a build log in any pane?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Apr 19, 2019 - 02:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I gave up trying to use the _delay_ms() command, I could never get it to work correctly on the ATtiny10.  Instead I used a counter to delay the program.  

Ian Stumpe

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

After reading all the comments and suggestions I finally decided to go pure AS7 with no Visual-Micro no Arduino layer.

I uploaded my small code and Bang! Voila!

The ATtiny85 is acting as it should. Timing behave correctly at 1MHz F_CPU and at 8MHz it goes 8 times too slow. Which is exactly what it should do.

It would appear that somewhere in Visual-Micro and or Arduino IDE the is a command that does not address the F_CPU as it should, which is another subject altogether, that is not on my priority list at the moment.

Thanks to all for getting involved. laugh

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

stumr84 wrote:

I gave up trying to use the _delay_ms() command, I could never get it to work correctly on the ATtiny10.  Instead I used a counter to delay the program.  

 

_delay_ms and _delay_us are just counters, nothing else.

During pre processing the number of cycles to be ' burned'  is calculated, like you did yourself.

that is then loaded in the used registers right before the actual routine is called.

Only pest that if you have a lot of interrupts running in the back ground, they will mess up your nicely calculated delay as they burn additional cycles, but you do not know how many as the interrupts are 'random' in appearance and length.

 

 

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

meslomp wrote:
_delay_ms and _delay_us are just counters, nothing else.

During pre processing the number of cycles to be ' burned'  is calculated, like you did yourself.

They are actual functions.

The calculation is done by the compiler proper,

hence the need to turn on optimization.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

Pages