728x90

Why is #define F_CPU have no effect on AVR code _delay_ms_() function?

 

Why is #define F_CPU have no effect on AVR code _delay_ms_() function?

I am programming an ATtiny85 with MS_Visual_Studio with extension Visual_Micro using an Arduino1.6/1.8 Gemma board definition. The programmer is Sparkfun Tiny Programmer. Here is the very simple code

stackoverflow.com

 

 

Viewed 2k times

 

0

I am programming an ATtiny85 with MS_Visual_Studio with extension Visual_Micro using an Arduino1.6/1.8 Gemma board definition. The programmer is Sparkfun Tiny Programmer.
Here is the very simple code utilized. ( Thanks to InsideGadgets YouTube channel " Change the ATtiny85 clock speed on the fly"). It couldn't get any simpler.

Yet, despite the fact that I change the #define F_CPU 1000000 to #define F_CPU 8000000, there is absolutely no effect on the LED flash cycling period, which is about 2 seconds.
The ATtiny85 act as if the clock was 1MHz, despite any changes to F_CPU.
I tested CLKPR = 3 over CLKPR = 0, which changes the prescaler from a factor of 1 to 8.
This should make the delay 8 times longer, which it does. I searched for some details about the F_CPU definition but could not find any explanation for this behavior.

The Question: Why is there no effect on the _delay_ms(1000) after the F_CPU has been defined from 1MHz to 8MHz?

#define F_CPU 1000000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> int main(void) { DDRB |= (1 << PB0); while (1) { PORTB |= (1 << PB0); // Toggle LED _delay_ms(1000); // delay 1 second PORTB &= ~(1 << PB0); _delay_ms(1000); // delay 1 second cli(); CLKPR = (1 << CLKPCE); // set for changing prescaler // Change clock prescaler to 0000 CLKPR = 0; // divider by 1 // CLKPR = 3; // divider by 8 sei(); } // complete Loop is a 2 seconds period return 0; }

avrattiny

share  improve this question  follow 

asked Apr 2 '19 at 21:55

Fred Cailloux

1137 bronze badges

  •  

    Are you sure that the macro is actually used during compilation? Where do you define it? You could check the value during runtime and verify that it really is set to what you expect. – Rev1.0 Apr 3 '19 at 9:05

  •  

    try #define F_CPU 8000000UL - note UL at the end. Without it probably functions are treating the value as 16-bit and truncating it, or replacing it with default – AterLux Apr 3 '19 at 11:53

  •  

    Also, make sure the macro is not defined in the compiler options (i.e. there is no-DF_CPU=1000000UL or something like that) – AterLux Apr 3 '19 at 12:00

add a comment

1 Answer

ActiveOldestVotes

0

 

The F_CPU just lets the _delay_ms() macro calculate how many cycles each second takes. You need this because the delay macros are very simple and do not know what the prescaller happens to be set to at the moment they are called at runtime.

So if you are going to be changing the prescaller on the fly, you might want to make two different delay functions so you can make it clear in your code what is going on.

It might look like...

#define F_CPU 1000000 // We start with 8x prescaler on 8Mhz clock #define delay_ms_1Mhz(x) (_delay_ms(x)) // Delay when prescaller set to 8x #define delay_ms_8Mhz(x) (_delay_ms(x*8)) // Delay when prescaller set to 1x so we need to burn 8x as many cycles

...and then decide which to call depending on what the prescaler is set to at that point in your code.

 

 

 

+ Recent posts