为什么#define F_CPU 对 AVR 代码 _delay_ms_() 函数没有影响?

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

我正在使用 Arduino1.6/1.8 Gemma 板定义为带有 MS_Visual_Studio 扩展名 Visual_Micro 的 ATtiny85 编程。程序员是Sparkfun Tiny Programmer。
这是使用的非常简单的代码。 (感谢 InsideGadgets YouTube 频道“Change the ATtiny85 clock speed on the fly)。再简单不过了。

然而,尽管我将#define F_CPU 1000000 更改为#define F_CPU 8000000,但对 LED 闪光循环周期(大约 2 秒)绝对没有影响。
尽管对 F_CPU.
进行了任何更改,但 ATtiny85 的行为就好像时钟是 1MHz 我在 CLKPR = 0 上测试了 CLKPR = 3,这将预分频比从 1 更改为 8。
这应该使延迟时间延长 8 倍,确实如此。 我搜索了有关 F_CPU 定义的一些详细信息,但找不到对此行为的任何解释。

问题:F_CPU定义1MHz到8MHz后,为什么对_delay_ms(1000)没有影响?

#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;
}

F_CPU 只是让 _delay_ms() 宏计算每秒需要多少个周期。您需要这个,因为延迟宏非常简单,并且不知道在运行时调用它们时预分频器恰好被设置为什么。

因此,如果您要即时更改预分频器,您可能需要创建两个不同的延迟函数,以便在您的代码中明确说明发生了什么。

它可能看起来像...

#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

...然后根据代码中预分频器的设置来决定调用哪个。