Der zitierte Satz ist keine Warnung, sondern lediglich eine Aussage darüber, wie die Dinge funktionieren.
Es ist an sich nichts Falsches daran, eine ordnungsgemäß geschriebene Interrupt-Routine zu verwenden millis()
oder zu verwenden micros()
.
Auf der anderen Seite ist es per definitionem falsch, irgendetwas in einer falsch geschriebenen Interruptroutine zu tun.
Eine Interruptroutine, die mehr als ein paar Mikrosekunden benötigt, um ihre Arbeit zu erledigen, ist höchstwahrscheinlich falsch geschrieben.
Kurz gesagt: Eine ordnungsgemäß geschriebene Interrupt-Routine verursacht oder stößt nicht auf Probleme mit millis()
oder micros()
.
Bearbeiten: In Bezug auf "Warum sich micros ()" unregelmäßig verhält ", wie in einer Webseite " Überprüfung der Arduino micros-Funktion " erläutert , ist micros()
Code auf einem gewöhnlichen Uno funktional äquivalent zu
unsigned long micros() {
return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}
Dies gibt ein vorzeichenloses Vier-Byte-Long zurück, das aus den drei niedrigsten Bytes von timer0_overflow_count
und einem Byte von dem Timer-0-Zählregister besteht.
Das timer0_overflow_count
wird vom TIMER0_OVF_vect
Interrupt-Handler ungefähr einmal pro Millisekunde inkrementiert , wie in einer Untersuchung der Webseite mit der Arduino-Millis-Funktion erläutert .
Bevor ein Interrupt-Handler gestartet wird, deaktiviert die AVR-Hardware Interrupts. Wenn (zum Beispiel) ein Interrupt-Handler fünf Millisekunden lang mit noch deaktivierten Interrupts ausgeführt wird, werden mindestens vier Timer-0-Überläufe übersehen. [Interrupts, die in C-Code im Arduino-System geschrieben wurden, sind nicht wiedereintrittsfähig (können mehrere überlappende Ausführungen innerhalb desselben Handlers korrekt verarbeiten), aber es könnte ein wiedereintrittsfähiger Assembler-Handler geschrieben werden, der Interrupts wieder aktiviert, bevor ein zeitaufwendiger Prozess beginnt.]
Mit anderen Worten, Timer-Überläufe stapeln sich nicht. Wenn ein Überlauf auftritt, bevor der Interrupt des vorherigen Überlaufs verarbeitet wurde, millis()
verliert der Zähler eine Millisekunde, und die Diskrepanz timer0_overflow_count
macht sich wiederum auch micros()
um eine Millisekunde negativ bemerkbar.
Betrachtet man "kürzer als 500 μs" als oberes Zeitlimit für die Interrupt-Verarbeitung, "um zu verhindern, dass der Timer-Interrupt zu lange blockiert", könnte man auf knapp 1024 μs (z. B. 1020 μs) aufsteigen und millis()
würde die meisten noch funktionieren Zeit. Ich betrachte einen Interrupt-Handler, der mehr als 5 μs als träge, mehr als 10 μs als träge und mehr als 20 μs als schneckenartig betrachtet.