Проблема с использованием micros() вместо millis()

У меня есть две реализации функций, которые, как я ожидал, будут работать одинаково:

#define HEAD_STEP_DELAY 1000
unsigned long HeadLastMicros;
void HeadUpdate()
{
    if ((micros()>=HeadLastMicros) && ((micros()-HeadLastMicros)<HEAD_STEP_DELAY)) {
        return;
    }
    HeadLastMicros = micros();
    HeadStep(true);
}

и

#define HEAD_STEP_DELAY 1
unsigned long HeadLastMillis;
void HeadUpdate()
{
    if ((millis()>=HeadLastMillis) && ((millis()-HeadLastMillis)<HEAD_STEP_DELAY)) {
        return;
    }
    HeadLastMillis = millis();
    HeadStep(true);
}

Я знаю, что разрешение micros() ограничено примерно 8us, но я полагаю, что, учитывая, что у меня ожидание 1000us, оба вышеперечисленных параметра должны быть относительно близки к одному и тому же поведению. Я управляю шаговым двигателем с помощью этого кода, и шаговый двигатель, который использовал micros(), вел себя неустойчиво. Я еще не навел на него оптический прицел, так что не знаю наверняка, но крутящий момент был значительно меньше (мотор легко глох), и он звучал шатко.

Я использую ATMEGA324A вместе с библиотекой MightyCore.

Есть ли что-то неправильное в моем подходе? Спасибо.

РЕДАКТИРОВАТЬ: я поместил область действия на него после моего первоначального сообщения, и период кода micros () составляет примерно половину периода кода millis ().

, 👍-1


1 ответ


4

Во-первых, когда имеешь дело с системой времени, которая постоянно меняется, не сравнивай два раза. Сравните различия.

Во-вторых, кэшируйте результаты вызова функции, если вы собираетесь использовать ее более одного раза.

В-третьих, если вам нужен постоянный временной интервал, попросите об этом. Ваш текущий код на основе micros() вполне может занять 1990 мкс на одних итерациях и 1001 мкс на других.

В-четвертых, не используйте текущее время более одного раза...

Сделайте что-то вроде (не указывая millis() или micros()):

unsigned long HeadLast; /* Это должно быть где-то инициализировано (HeadStart()?),
                           потому что в противном случае все может пойти странно.  
                           На платформе Arduino инициализация равна 0
                           может сработать.  В других системах время может начаться в любой момент.
                           Это привело к тому, что у Microsoft Windows возникли проблемы после
                           работает в течение 49 дней (начато с 0), в то время как X Windows
                           не имеет такой проблемы (запускайте в любое время).
                           */
void HeadUpdate()
{
    /* скомпилируйте с помощью -O, и это оптимизирует работу с регистром. */
    unsigned long now = get_time_function();

    /* Нам не нужно тестировать сейчас >= HeadLast, так как время монотонно. */
    if ((now-HeadLast)<HEAD_STEP_DELAY)) {
        return;
    }
    /* Выберите время, в которое, по нашему мнению, это началось.  
       Это вполне может произойти раньше текущего времени. */
    HeadLast += HEAD_STEP_DELAY;
    HeadStep(true);
}
,