Ошибка времени выполнения с таймером прерывания на Atmega2560

#interrupt #atmega

#прерывание #atmega

Вопрос:

Я пытаюсь заставить цикл регулярно выполняться каждые 50 миллисекунд на Atmega 2560. Использование простой функции задержки не сработает, потому что общее время цикла в конечном итоге равно времени, которое потребовалось для выполнения других функций в цикле, плюс ваше время задержки. Это работает еще хуже, если вызовы ваших функций занимают переменное время, что обычно и происходит.

Чтобы решить эту проблему, я реализовал простой класс timer:

 volatile unsigned long timer0_ms_tick;
    timer::timer()
    {
        // Set timer0 registers
        TCCR0A = 0b00000000; // Nothing here
        TCCR0B = 0b00000000; // Timer stopped, begin function start by setting last three bits to 011 for prescaler of 64
        TIMSK0 = 0b00000001; // Last bit to 1 to enable timer0 OFV interrupt enable
        sei(); // Enable global interrupts
    }

    void timer::start()
    {
        timer0_ms_tick = 0;

        // Set timer value for 1ms tick (2500000 ticks/sec)*(1 OFV/250 ticks) = 1000OVF/sec
        // 256ticks - 250ticks - 6 ticks, but starting at 0 means setting to 5
        TCNT0 = 5;

        // Set prescaler and start timer
        TCCR0B = 0b00000011;
    }

    unsigned long timer::now_ms()
    {
        return timer0_ms_tick;
    }

    ISR(TIMER0_OVF_vect)
    {
        timer0_ms_tick =1;
        TCNT0 = 5;
    }
  

Основной цикл использует это следующим образом:

 unsigned long startTime, now;
    while(true)
    {
        startTime = startup_timer.now_ms();

        /* Loop Functions */

        // Wait time step
        now = startup_timer.now_ms();
        while(now-startTime < 50)
        {
            now = startup_timer.now_ms();

        }

        Serial0.print(ltoa(now,time_string, 10));
        Serial0.writeChar('-');
        Serial0.print(ltoa(startTime,time_string, 10));
        Serial0.writeChar('=');
        Serial0.println(ltoa(now-startTime,time_string, 10));
    }
  

Мой вывод выглядит следующим образом:

 11600-11550=50                                                                                                       
11652-11602=50                                                                                                       
11704-11654=50                                                                                                       
11756-11706=50                                                                                                       
12031-11758=273                                                                                                      
11828-11778=50                                                                                                       
11880-11830=50                                                                                                       
11932-11882=50                                                                                                       
11984-11934=50                                                                                                       
12036-11986=50                                                                                                       
12088-12038=50                                                                                                       
12140-12090=50                                                                                                       
12192-12142=50                                                                                                       
12244-12194=50                                                                                                       
12296-12246=50                                                                                                       
12348-12298=50                                                                                                       
12400-12350=50                                                                                                       
12452-12402=50                                                                                                       
12504-12454=50                                                                                                       
12556-12506=50                                                                                                       
12608-12558=50                                                                                                       
12660-12610=50                                                                                                       
12712-12662=50                                                                                                       
12764-12714=50                                                                                                       
12816-12766=50                                                                                                       
12868-12818=50                                                                                                       
12920-12870=50                                                                                                       
12972-12922=50                                                                                                       
13024-12974=50                                                                                                       
13076-13026=50                                                                                                       
13128-13078=50                                                                                                       
13180-13130=50                                                                                                       
13232-13182=50                                                                                                       
13284-13234=50                                                                                                       
13336-13286=50                                                                                                       
13388-13338=50                                                                                                       
13440-13390=50                                                                                                       
13492-13442=50                                                                                                       
13544-13494=50                                                                                                       
13823-13546=277                                                                                                      
13620-13570=50
  

Кажется, что большую часть времени это работает хорошо, но время от времени что-то странное происходит со значениями синхронизации. Я думаю, что это как-то связано с прерыванием, но я не уверен, что именно. Любая помощь была бы высоко оценена.

Комментарии:

1. Есть ли у вас какие-либо другие прерывания, которые вы обслуживаете?

2. Других прерываний быть не должно.