Scriu o funcție de temporizare care utilizează funcția micros () care generează o valoare lungă nesemnată. Pentru a compensa o condiție de răsturnare, aș dori să folosesc valoarea maximă pentru acel tip de variabilă. Am un număr, 4.294.967.295, dar mă așteptam să fie o constantă undeva.
Există o constantă MAX_UNSIGNED_LONG în fișierele compilatorului Arduino undeva?
Am încercat acest nume și știu că probabil nu este asta. Încă mă bag în cap.
Răspunde
Diverse fișiere limits.h
din ierarhia avr-gcc
definesc ULONG_MAX
, care poate fi valoarea de exemplu, în sistemul meu, astfel de fișiere au căi care se termină cu hardware/tools/avr/lib/gcc/avr/4.8.1/include-fixed/limits.h
sau cu hardware/tools/avr/lib/gcc/avr/4.8.1/install-tools/include/limits.h
și conțin definiții precum următoarele.
/* Maximum value an `unsigned long int" can hold. (Minimum is 0). */ #undef ULONG_MAX #define ULONG_MAX (LONG_MAX * 2UL + 1UL)
Notă, LONG_MAX
este, de asemenea, definit în limits.h
.
Notă, aritmetica realizată într-o formă ca
timeDelta = micros() - prevTime;
va fi corectă (indiferent dacă micros()
debordat) pentru timp scurs până la 2³² microsecunde, sau aproximativ 4295 secunde.
Răspuns
Nu este nevoie să compensați o condiție de răsturnare „.
Vedeți răspunsul meu: https://arduino.stackexchange.com/a/33577/10794
într-un compilator Arduino?
Compilatorul „Arduino” este un compilator C ++. Acesta este punctul de plecare pentru majoritatea întrebărilor. Dacă utilizați Google pentru:
maximum unsigned long in c++
Veți găsi primul link care duce la:
http://www.cplusplus.com/reference/climits/
Prin faptul că scrie:
ULONG_MAX Maximum value for an object of type unsigned long int
Răspuns
Ați încercat să faceți acest lucru ?:
unsigned long maxUnsignedLong = 0UL - 1UL;
sau:
const unsigned long ULONG_MAX = 0UL - 1UL;
Răspuns
Din rețea, mi se pare, nu este atât de ușor să găsiți răspunsul corect la valoarea maximă a micros () a propriilor mele plăci arduino.
În cazul meu , se pare că micros () se rotește aproximativ la fiecare 17 secunde. În cele din urmă, am scris Setup () pentru ca eu să prind 0x1111111 ca valoare maximă a micros () după cum urmează.
void setup () { Serial.begin( 115200 ); // set the baud rate for writing messages. int go = 1; // set the flag to continue do-while loop; int n, nMin = 0, nMax = 0; // see how many more the numbers of calling micros() to get different value; int d, dMin, dMax; // see the time interval of micros() having different values; unsigned long currT; // the time of current micros() calling unsigned long lastT = micros(); // the time of last micros() calling unsigned long T[200]; // keep tracking 200 different lastT values int it = 0; // use T[it%200] to keep each lastT (circular buffer) do { n = 0; while( (currT=micros()) == lastT ) n++; // get a different value T[ (it++) % 200 ] = currT; // save the value d = currT - lastT; // get the difference if ( d<0 ) { // if micros() rolls over go = 0; // stop this do-while loop Serial.println(); // print new line for ( int i=it-200, j=0; i<it; i++ ) { Serial.printf( "%9x", T[i%200] ); // the last 200 different lastT values 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 ); }
Comentarii
- rafinați comentariul " int n, nMin = 0, nMax = 0; "
- Nu, acest lucru este complet greșit . Consultați arduino.cc/en/Reference/Micros acolo este dat un timp de rulare de aproximativ 70 de minute, care se potrivește cu maximul unei lungimi nesemnate în microsecunde, convertite în minute (de fapt, 71 de minute și jumătate)
- Ei bine, am ' văzut timpul de răsturnare de aproximativ 70 de minute. Dar, chiar nu ' nu știu de ce, pe placa mea wifi wifi esp32, apelul micros () se rotește aproximativ la fiecare 17 secunde. Ați putea să-l imaginați?
- Acest tip de " îl surprindeți în actul " experiment este greșit pentru început , dar apoi se amestecă mai mult în diferențele AVR față de ESP – de exemplu, acest cod nu ar fi ' nici măcar valid pe un AVR, unde% d ar interpreta greșit un lung nesemnat – s-ar putea " aproape " funcționează pe un ESP32, dar ar amesteca în continuare bitul de semn. Ar trebui să citiți cu adevărat documentația sau codul sursă al nucleului.
- Am constatat că de fapt wifiboy esp32 rulează la 240 Mhz. Deci, valoarea maximă nesemnată lungă a macros () 0xffffffff / 240 este 0x1111111. Exact asta am primit. Mulțumesc foarte mult!