Ich bezweifle, dass der Mikrocontroller mehrere Interrupt-Routinen für einen einzelnen Timer unterstützt.
Zum Beispiel ein einzelner Timer, der bei 5 ms, 10 ms, 1 s usw. unterbricht. In meinem Design verwende ich 3 Timer: Ein Timer unterbricht alle 1 ms für eine Statusprüfung, andere zwei bei 50 ms und 1 s.
Ich bin neugierig zu wissen, warum ich keinen Controller haben kann, der mehr als eine ISR hat, und auch, warum er anstelle von Interrupts bei Timer-Überlauf nicht bei seiner Periodenübereinstimmung unterbrechen kann.
Es mag einige geben, die diese Fähigkeit haben, aber die meisten nicht. Sie müssen die verstrichenen Zyklen zählen und von dort an die entsprechende Routine delegieren.
Nein, aber es gibt viele Mikrocontroller mit mehreren Timern, von denen jeder Lauf in unterschiedlichen Intervallen Interrupts auslösen kann.
Natürlich benötigt jeder Timer seine eigene Interrupt-Routine. Es sieht nicht so aus, als würden Sie Ihren 5-ms-Interrupt genauso behandeln wollen wie einen 1-s-Interrupt, aber wenn Sie auf diese Art von Architektur fest eingestellt wären, können alle Interrupt-Routinen denselben Code enthalten. Das würde natürlich etwas zusätzlichen Programmspeicher verbrauchen, selbst wenn Sie nur alle Interrupts dieselbe Unterroutine aufrufen lassen.
Ich kann nur für AVRs sprechen, aber ich weiß, dass die, die ich benutzt habe, nur 2-3 Timer hatten. Aber ich sehe keine Notwendigkeit, mehrere Timer zu verwenden. Sie können einfach einen verwenden, bei dem der Prescaler und der Vergleichswert des Timers konfiguriert sind, bei dem in einem bekannten Zeitintervall (z. B. alle 1 ms) ein Vergleichs-ISR ausgelöst wird. Sie können dann die Zeit verfolgen und eine switch-Anweisung haben, um zu steuern, welche Aktion Sie ausführen möchten.
Timer-ISR mit variabler Periode ist ziemlich einfach zu erreichen.
Variante 1. Timer haben normalerweise ein Countdown-Register, das durch den Code aktualisiert werden kann. Der Countdown-Anfangswert kann im ISR selbst von Fall zu Fall aktualisiert werden. Eine Zustandsmaschine kann verwendet werden, um zu entscheiden, welcher Anfangswert dem Zähler zugewiesen wird.
Variante 2. Eine andere Möglichkeit besteht darin, den Timer auf die kürzeste Dauer einzustellen und dann die Interrupts zu zählen, wenn Sie eine längere Dauer benötigen. Zum Beispiel müssen Sie alle 5 ms, 10 ms, 1 s 3 verschiedene Dinge tun. Stellen Sie den Timer auf 5 ms ein, innerhalb der ISR wird bei jedem ISR-Aufruf ein Zähler** erhöht. Vergleichen Sie in der main()
Schleife den Zähler mit Schwellenwerten. Für eine Dauer von 10 ms wäre der Schwellenwert 2, für 1 s wäre der Schwellenwert 200. Sobald der Zähler gleich dem Schwellenwert ist, wird das main()
getan, was in diesem Intervall getan werden muss. Das Gute an diesem Ansatz ist, dass Sie einen Timer und einen ISR haben können, aber mehrere Schwellenwerte (bei Bedarf auch mehrere Zähler). Das variable Timing würde eher im Code als im Hardware-Timer implementiert werden.
Beachten Sie, dass dieser Ansatz a erfordertmain()
Schleife, die immer schneller als das kürzeste Intervall wiederholt wird. Die Genauigkeit des Timings sollte ebenfalls berücksichtigt werden. Wenn dies zu einem Problem wird, gibt es Variationen dieses Musters, die mit einer langsameren main()
Schleife funktionieren können.
** Zähler und Flags sind globale Variablen, die sowohl für ISR als auch sichtbar sindmain()
Kohlschmied
tamil_innov
Kohlschmied