为什么#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
...然后根据代码中预分频器的设置来决定调用哪个。
我正在使用 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
...然后根据代码中预分频器的设置来决定调用哪个。