Есть ли константа для максимального значения Unsigned Long в компиляторе Arduino?
Я пишу функцию таймера, использующую функцию micros(), которая генерирует длинное значение без знака. Чтобы компенсировать условие пролонгации, я хотел бы использовать максимальное значение для этого типа переменной. У меня есть число 4 294 967 295, но я ожидал, что оно где-то будет постоянным.
Есть ли где-нибудь в файлах компилятора Arduino константа MAX_UNSIGNED_LONG?
Я попробовал это имя и знаю, что оно, вероятно, не то. Все еще ковыряюсь.
@Rich Maes, 👍5
4 ответа
Лучший ответ:
Различные файлы 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 секунд.
Вам не нужно "компенсировать условие пролонгации".
Посмотрите мой ответ: 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
По сети, как мне кажется, не так просто найти правильный ответ максимального значения 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 );
}
Вы пытались это сделать?:
unsigned long maxUnsignedLong = 0UL - 1UL;
или:
const unsigned long ULONG_MAX = 0UL - 1UL;
- Как заставить компилятор гарантировать, что выделение памяти для локальных переменных не приведет к переполнению оперативной памяти во время выполнения?
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
уточнить комментарий "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