Почему #define F_CPU не влияет на функцию кода AVR _delay_ms_ ()? - PullRequest
0 голосов
/ 03 апреля 2019

Я программирую ATtiny85 с MS_Visual_Studio с расширением Visual_Micro, используя определение платы Gemma Arduino1.6 / 1.8.Программист - Sparkfun Tiny Programmer.
Вот очень простой используемый код.( Благодаря каналу YouTube InsideGadgets " Изменение тактовой частоты ATtiny85 на лету " ).Это не может быть проще.

Тем не менее, несмотря на то, что я заменяю #define F_CPU 1000000 на #define F_CPU 8000000, это абсолютно не влияет на период циклической смены светодиодов, который составляет около 2 секунд..
ATtiny85 работает так, как если бы тактовая частота была 1 МГц, несмотря на любые изменения в F_CPU.
Я проверил CLKPR = 3 по CLKPR = 0, что изменяет прескалер с коэффициента от 1 до 8.
Это должносделать задержку в 8 раз дольше, что делает.Я искал некоторые подробности об определении F_CPU, но не смог найти никакого объяснения этому поведению.

Вопрос : Почему на _delay_ms (1000) не влияют после того, как F_CPU былопределяется от 1 МГц до 8 МГц?

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

1 Ответ

0 голосов
/ 03 апреля 2019

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

... и затем решите, какой вызов вызывать, в зависимости от того, какой прескалер установлен в данный момент в вашем коде.

...