Эквивалент millis() в студии Atmel

Этот код работает в студии Atmel. Но эта функция миллис начинает работать на 31-34 миллисекунды позже, чем функция ардуино миллис. Почему? Я добавляю изображение.

Изображение: https://imageshack.com/a/img922/3060/ umtNJp.jpg

Обновление 2

#define F_CPU 8000000UL
#include <avr/io.h>

#include <avr/interrupt.h>

#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
// дробное количество миллисекунд на переполнение таймера 0. мы сдвигаем вправо
// на три, чтобы уместить эти числа в байт. (для тактовой частоты мы заботимся
// около - 8 и 16 МГц - точность не теряет.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)
volatile unsigned long timer0_overflow_count = 0;
volatile unsigned long timer0_millis = 0;
static unsigned char timer0_fract = 0;

volatile uint8_t count;

ISR (TIMER0_OVF_vect)

{


    unsigned long m = timer0_millis;
    unsigned char f = timer0_fract;

    m += MILLIS_INC;
    f += FRACT_INC;
    if (f >= FRACT_MAX) {
        f -= FRACT_MAX;
        m += 1;
    }

    timer0_fract = f;
    timer0_millis = m;
    timer0_overflow_count++;





}

unsigned long millis()
{
    unsigned long m;
    uint8_t oldSREG = SREG;

    // отключаем прерывания, пока мы читаем timer0_millis, иначе мы можем получить
    // противоречивое значение (например, в середине записи в timer0_millis)
    cli();
    m = timer0_millis;
    SREG = oldSREG;

    return m;
}



int main (void)

{
    DDRB |= (1<<0); 
    TCNT0 = 0;
    count = 0;
    TCCR0B |= (0<<CS02) | (1<<CS01) | (1<<CS00); // ПРЕДСКАЛЕР 64
    TIMSK0 = (1<<TOIE0);
    sei();

    while(1)  
    {
        millis() to uart.

    }

}

, 👍1

Обсуждение

перекрестная публикация https://stackoverflow.com/questions/53780848/using-of-millis-in-atmel-studio, @Juraj


1 ответ


4

Функция millis() определена в Arduino Core для архитектуры AVR, в частности файл wiring.c.< /п>

Вы можете видеть, что timer0 настроен с различными параметрами для предварительного масштабирования, запуска прерываний и обработки переполнения timer0, так что переменная с именем timer0_millis содержит количество миллисекунд, прошедших с момента запуска эскиза.

Функция millis() по сути возвращает значение timer0_millis.

Если вы хотите использовать эту функцию в AVR Studio, вам необходимо включить ту же настройку таймера 0 и обработку прерываний/переполнения, что и ядро Arduino.

,

Я нашел пример кода, но это не тот же код. Можете ли вы написать эквивалент кода, приведенного выше? для примера и моего обучения. Конечно, если это возможно? Спасибо., @alex jla

Я не буду писать это для вас. Это уже написано в проводке.c, @jose can u c

ох, извините, я не видел файл Wiring.c. Я добавил его в свой проект. Но я не использую timer0_millis. Ошибка: «timer0_millis» необъявлен (первое использование в этой функции). Что я могу добавить в свой проект Wiring.c?, @alex jla

Вам нужно будет прочитать файл Wiring.c, понять его, а затем реализовать в своем собственном проекте. Arduino делает очень простыми вещи, которые сложны в программировании AVR. По какой причине вы решили использовать AVR Studio?, @jose can u c

Потому что я изучаю Atmel Studio. Но теперь мне нужна эта функция. Не нужно усложнять ее. Просто я хочу счетчик, например, millis(), который имеет прямое направление. Мне нужно решение., @alex jla

Я не пытаюсь показаться придурком, но здесь МНОГО сложностей и опций, которые упрощается с помощью Arduino. В своем ответе я сказал, что millis() в основном возвращает timer0_millis, однако эта переменная получает свое значение из подпрограммы обслуживания прерываний, вызванной переполнением. Не существует ответа «просто дайте код» — изучить AVR Studio — значит изучить архитектуру AVR. К счастью, файл Wiring.c и включенные в него файлы содержат все необходимое для реализации millis() в вашем собственном проекте., @jose can u c

Если для миллиса достаточно файла Wiring.c, то ты можешь дать мне код. Просто скопируй и вставь, братан. Я обещаю узнать, как это работает. Но сейчас мне это действительно нужно. И я пытаюсь запустить часть Wiring.c, я не беги. Добрых дней., @alex jla

Просить пользователей просто предоставить вам код — не лучший способ получить что-либо, особенно понимание того, как он должен работать., @selectstriker2

Вы уже получили ответ @alexjla, пришло время учиться, если вы хотите учиться, @Roberto Lo Giacco

@alexjla, я дал тебе на SO ссылку на форум AVR. есть код https://www.avrfreaks.net/comment/907712#comment-907712, @Juraj