Как обработать двойной ролловер micros()?

Я знаю, что могу справиться с одним опрокидыванием с помощью вычитания:

if (micros() - lastTime > period) {
  lastTime = micros();
  ...
}

Но как с этим справиться, если это не true или оно не проверяется более 70 минут (без использования uint64_t)?

, 👍1

Обсуждение

В чем заключаются возражения против использования millis(), если вы измеряете довольно длительные периоды времени?, @Nick Gammon

Я использую свою реализацию micros() и не хочу реализовывать millis(), потому что это увеличивает ISR. А еще точность., @Vasil Kalchev

Чтобы внести ясность: вы нас спрашиваете об **вашей** версии микросхем? Как насчет размещения на нем кода?, @Nick Gammon

Это то же самое, что и версия Arduino, за исключением того, что в ISR(TIMER0_OVF_vect) есть одно приращение переменной. Код должен выполняться с как можно меньшим количеством перерывов, и я хочу иметь возможность запускать что-то с нерегулярными длинными интервалами., @Vasil Kalchev

Это то же самое, что и версия Arduino, но совершенно другая, не так ли? Я так понимаю, это сверхсекретный код., @Nick Gammon

Это то же самое, и это не имеет ничего общего с вопросом: « #define clockCyclesPerMicro Second() ( F_CPU / 1000000L ) летучий uint32_t timer0OverflowCount = 0; ИСР(TIMER0_OVF_vect) { ++timer0OverflowCount; } uint32_t нас() { uint32_t м; uint8_t т; uint8_t oldSREG = SREG; Кли(); м = таймер0OverflowCount; т = TCNT0; if (((TIFR0 & (1 << TOV0)) && (t < 255))) ++m; СРЭГ = старыйСРЭГ; return ((m << 8) + t) * (64 / clockCyclesPerMicro Second()); } `, @Vasil Kalchev

в чем именно проблема?: Вы хотите, чтобы период длился более 70 минут?, @Gerben


1 ответ


Лучший ответ:

3

Если вы хотите измерить время длительностью более 70 минут с помощью micros(), вам придется использовать uint64_t, и ничего это неправильно.

Код должен работать с как можно меньшими перерывами [...]

Вам не нужно выполнять 64-битную арифметику внутри ISR. Вы могли бы очень хорошо реализовать 32-битную версию, управляемую прерываниями, а затем расширить его до 64 бит в контексте без прерываний. Пример:

// Ваша реализация на основе ISR.
uint32_t micros32();

// Расширяем до 64 бит.
uint64_t micros64() {
    static uint64_t time64;
    time64 += micros() - (uint32_t) time64;
    return time64;
}

Это должно работать, если вы вызываете micros64() достаточно часто. Предположительно, у вас будет что-то вроде if (micros64() - LastTime > период) { ... внутри вашего цикла, так что это не должно быть проблемой, если вы никогда не блокируете ваш цикл.

На самом деле, вы можете продвинуть эту идею еще дальше. Если вы можете это гарантировать micros64() будет вызываться не реже одного раза каждые 65,5 мс, после чего вы ваш ISR может увеличиваться только на 16-битный счетчик.

,

Спасибо, это решит проблему. Последняя часть будет хорошей дальнейшей оптимизацией для моего случая., @Vasil Kalchev