Есть ли константа для максимального значения Unsigned Long в компиляторе Arduino?

Я пишу функцию таймера, использующую функцию micros(), которая генерирует длинное значение без знака. Чтобы компенсировать условие пролонгации, я хотел бы использовать максимальное значение для этого типа переменной. У меня есть число 4 294 967 295, но я ожидал, что оно где-то будет постоянным.

Есть ли где-нибудь в файлах компилятора Arduino константа MAX_UNSIGNED_LONG?

Я попробовал это имя и знаю, что оно, вероятно, не то. Все еще ковыряюсь.

, 👍4


4 ответа


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

9

Различные файлы limits.h в иерархии avr-gcc определяют ULONG_MAX, который может быть нужным вам значением. Например, в моей системе пути к таким файлам заканчиваются на hardware/tools/avr/lib/gcc/avr/4.8.1/include-fixed/limits.h или на hardware/tools /avr/lib/gcc/avr/4.8.1/install-tools/include/limits.h и содержать определения, подобные приведенным ниже.

/* Максимальное значение, которое может содержать `unsigned long int'. (минимум 0). */
#undef ULONG_MAX
#define ULONG_MAX (LONG_MAX * 2UL + 1UL)

Примечание: LONG_MAX также определяется в limits.h.

Обратите внимание, арифметические действия выполняются в форме, подобной

timeDelta = micros() - prevTime;

будет правильным (независимо от переполнения micros()) для прошедшего времени до 2³² микросекунд или около 4295 секунд.

,

3

Вам не нужно "компенсировать условие пролонгации".

Посмотрите мой ответ: https://arduino.stackexchange.com/a/33577/10794


в компиляторе Arduino?

Компилятор «Arduino» — это компилятор C++. Это отправная точка для большинства вопросов. Если вы используете Google для:

maximum unsigned long in c++

Вы обнаружите, что первая ссылка ведет на:

http://www.cplusplus.com/reference/climits/

В нем говорится:

ULONG_MAX   Maximum value for an object of type unsigned long int
,

-3

По сети, как мне кажется, не так просто найти правильный ответ максимального значения micros() и моих собственных плат arduino.
В моем случае кажется, что micros() переворачивается примерно каждые 17 секунд. Наконец, я написал Setup() для себя, чтобы поймать 0x1111111 как максимальное значение micros() следующим образом.

void setup () {
  Serial.begin( 115200 ); // устанавливаем скорость передачи для записи сообщений.
  int go = 1; // устанавливаем флаг для продолжения цикла do-while;
  int n, nMin = 0, nMax = 0; // смотрим, сколько еще вызовов micros(), чтобы получить другое значение;
  int d, dMin, dMax; // посмотреть временной интервал micros() с разными значениями;
  unsigned long currT; // время вызова текущего micros()
  unsigned long lastT = micros(); // время последнего вызова micros()
  unsigned long T[200]; // продолжаем отслеживать 200 различных значений lastT
  int it = 0; // используем T[it%200] для сохранения каждого lastT (циклический буфер)
  do {
    n = 0;
    while( (currT=micros()) == lastT ) n++; // получаем другое значение
    T[ (it++) % 200 ] = currT; // сохранить значение
    d = currT - lastT; // получаем разницу
    if ( d<0 ) { // если micros() переворачивается
      go = 0; // остановить этот цикл do-while
      Serial.println(); // печатаем новую строку
      for ( int i=it-200, j=0; i<it; i++ ) {
        Serial.printf( "%9x", T[i%200] ); // последние 200 различных значений lastT
        if ( ++j%5==0 ) Serial.println(); //
      }
      Serial.printf("\nat %d ms lastT 0x%x currT 0x%x n=[%d..%d] d=[%d..%d]\n",
        millis(), lastT, currT, nMin, nMax, dMin,dMax);
    }
    if ( !nMin && !nMax ) nMin = nMax = n, dMin = dMax = d;
    if ( nMin>n ) {
      PRINTF( "\nat %d ms nMin %d > n %d ", millis(), nMin, n);
      nMin = n;
    } else if ( nMax<n ) {
      PRINTF( "\nat %d ms nMax %d < n %d", millis(), nMax, n );
      nMax = n;
    }
    if ( dMin>d ) dMin = d;
    else if ( dMax<d ) dMax = d;
    lastT = currT;
  } while( go );
}
,

уточнить комментарий "int n, nMin = 0, nMax = 0;", @sam suan chen

**Нет, это совершенно неправильно**. См. https://www.arduino.cc/en/Reference/Micros, где указано время переноса около 70 минут, что соответствует максимальному значению unsigned long в микросекундах, преобразованному в минуты (фактически 71 с половиной минуты), @Chris Stratton

Ну, я видел, что время опрокидывания составляет около 70 минут. Но я действительно не знаю, почему на моей плате wifi boy esp32 вызов micros() переключается примерно каждые 17 секунд. Не могли бы вы представить это?, @sam suan chen

Этот вид эксперимента «поймай его в действии» с самого начала ошибочен, но затем он еще больше запутывается в различиях AVR и ESP — например, этот код не будет действителен даже на AVR, где %d неправильно интерпретирует unsigned long — это может «почти» работать на ESP32, но все равно перепутает знаковый бит. Вы действительно должны прочитать документацию или исходный код ядра., @Chris Stratton

Я обнаружил, что на самом деле мой wifiboy esp32 работает на частоте 240 МГц. Таким образом, максимальное беззнаковое длинное значение macros() 0xffffffff / 240 равно 0x1111111. Это именно то, что я получил. Большое спасибо!, @sam suan chen

«Ну, я видел, что время опрокидывания составляет около 70 минут». это зависит от частоты вашей системы. чем он быстрее, тем скорее ролл-овре., @dannyf

Нет, если ваш порт Arduino не сломан и на самом деле не реализует Arduino, время прокрутки micros() не имеет ничего общего с тактовой частотой системы - Arduino определяет это как unsigned long, чтобы считать **микросекунды (не системные часы). )** и, таким образом, для переноса через чуть более 70 минут. В лучшем случае у вас есть отчет об ошибке для разработчиков ESP32, но **вы не опубликовали ответ на этот вопрос Arduino-UNO**., @Chris Stratton


3

Вы пытались это сделать?:

unsigned long maxUnsignedLong = 0UL - 1UL;

или:

const unsigned long ULONG_MAX = 0UL - 1UL;
,