Ist es möglich, mehrere ISR-Routinen für einen einzelnen Timer im Mikrocontroller zu haben?

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.

Bitte erklären Sie, was Sie versuchen, was Sie versucht haben und was Ihre Fragen sind. Im Moment stimme ich dafür, dass ich schließe, da diese Frage mit zwei Sätzen keines dieser Dinge demonstriert und einen grundlegenden Mangel an Respekt für die Menschen zeigt, die versuchen, Ihnen zu helfen.
In meinem Design verwende ich 3 Timer, in denen ein Timer alle 1 ms für eine Statusprüfung unterbricht, andere zwei bei 50 ms und 1 s. Ich bin neugierig zu wissen, warum ich keinen Controller haben kann, der mehr als ISR und auch anstelle von Interrupts hat Warum kann es bei Timer-Überlauf nicht bei seiner Periodenübereinstimmung unterbrechen?
Vielen Dank, dass Sie die Frage bearbeitet und weitere Details ausgefüllt haben. Ich habe jetzt für die Wiedereröffnung gestimmt und kann eine Antwort geben, sobald es wiedereröffnet wurde.

Antworten (4)

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.

Wenn möglich, könnten Sie ein paar Controller nennen, damit ich das Datenblatt überprüfen kann
Mir ist noch nie jemand mit dieser Fähigkeit begegnet.
Der von uns verwendete Coldfire hat einen Allzweck-Timer, der ein "Master"-Timer-Register hat, an dem mehrere Hardware-Vergleichs-/Zähl-Interrupts hängen, was sozusagen die Funktionalität ist, nach der Sie suchen. Ich würde Ihrem Timer-Interrupt jedoch einfach eine einzeilige mathematische Prüfung oder einen statischen Zähler hinzufügen, sodass Sie jedes Mal, wenn der Zähler ein Modul einer bestimmten Zahl ist, einige Dinge tun können.
Zumindest einige MSP430-Geräte unterstützen mehrere Erfassungs-/Vergleichsregister innerhalb eines einzelnen Timer-Blocks. Siehe beispielsweise MSP430 Series 5 User Guide . Das Erfassungs-/Vergleichsregister 0 erzeugt einen Interrupt und die anderen Erfassungs-/Vergleichsregister erzeugen einen weiteren Interrupt. Innerhalb dieses anderen Interrupts können Sie feststellen, welches Erfassungs-/Vergleichsregister den Interrupt initiiert hat, und sich entsprechend verhalten. Mit einem einzigen MSP430-Timer-Block können Sie mehrere (bis zu sieben) periodische Interrupts mit unterschiedlichen Frequenzen erzeugen.
@kkrambo: Vielleicht unterschiedliche Timings, aber sie teilen sich alle die gleiche Frequenz, da der Timer größtenteils freilaufend ist.

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.

Was ist, wenn Sie eine langsame Schleife und eine schnelle Schleife haben? Was ist, wenn Sie eine Zeitüberschreitung verfolgen müssen? Was ist mit der Verwendung eines Timers für eine Software-Entprellung? Diese Mehrfach-Timer wurden nicht in das Paket gesteckt, weil Platz übrig war.
Ich habe nie gesagt, dass ein Timer alles ist, was für alle von Ihnen genannten Probleme benötigt wird. Seine Nähte, nach denen alle Operationen suchen, sind eine Möglichkeit, verschiedene Verfahren basierend auf der Zeit durchzuführen, und dies kann mit einem Timer durchgeführt werden.

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()

Leider sind viele Zeitgeber sehr eingeschränkt hinsichtlich der Umstände (falls vorhanden), unter denen ihre Countdown-Register geschrieben werden können, ohne den resultierenden Zeitabläufen eine beträchtliche Unsicherheit hinzuzufügen. Ein schöneres Design, wenn die Hardware dies unterstützt, besteht darin, einen Zähler zu verwenden, der einfach kontinuierlich läuft und nie beschrieben wird, zusammen mit einem "Vergleichs" -Register. Möglicherweise muss nach dem Schreiben des Vergleichsregisters überprüft werden, ob der Zähler beim Schreiben den gewünschten Wert nicht überschritten hat (in diesem Fall den Interrupt so schnell wie möglich auslösen), dies ermöglicht jedoch ein saubereres Timing als Countdown-Timer.