Polling oder Timer-Interrupt?

8

Wir hoffen, einen einfachen Linienfolger-Roboter bauen zu können, und wir hatten ein Problem, als wir über die PIC-Programmierung diskutierten.

Wir planten, eine Endlosschleife zu schreiben, den Messwert des Sensorfelds zu überprüfen und die relevanten Dinge für diesen Messwert zu tun.

Aber einer unserer Freunde sagte uns, wir sollten einen Timer-Interrupt verwenden, um Interrupts in bestimmten Zeiträumen zu erzeugen, und bei jedem Interrupt den Messwert des Sensorfelds überprüfen und die relevanten Dinge für diesen Messwert tun.

Aber wir können nicht herausfinden, welches das Beste ist: die Endlosschleife in der Hauptmethode ODER die Timer-Interrupt-Methode.

Was ist der beste Weg und warum?

RONEY
quelle
1
Sie haben vergessen zu fragen: "Gibt es einen besten Weg?" Für ein einfaches System ist es manchmal am besten, die Timer-Hardware zum Setzen eines Flags zu verwenden und dann den Regelkreis auszuführen, wenn das Flag gesetzt ist. Für ein komplexes System sind ISRs (und oft eine Art Betriebssystemkern oder zumindest ein Task-Switcher) oft am besten.
TimWescott

Antworten:

8

Der Prozessor muss etwas ausführen. Sie werden immer eine "Endlosschleife" haben, selbst wenn Sie in einem Interrupt-Handler arbeiten.

Die beste Lösung hängt davon ab, was Sie genau tun möchten.

Der Hauptvorteil der Verwendung von Interrupts besteht darin, dass Sie Ereignisse in Echtzeit bedienen können, während Ihr Hauptprogramm etwas anderes ausführt. Mit Timer-Interrupts können Sie bestimmte periodische Aktivitäten auf einer ziemlich genauen Zeitbasis ausführen, während Sie eine andere Verarbeitung durchführen.

Für die meisten Steueralgorithmen ist es nützlich, eine Art Zeitbasis (oder feste Frequenz) zu haben. Wenn das alles ist, was Ihre CPU tut, können Sie dies problemlos ohne Unterbrechungen tun, indem Sie entweder die Anzahl der Zyklen / Anweisungen in Ihrem Regelkreis steuern oder den Timer abfragen. Beide Methoden wären einfacher und effizienter als die Verwendung von Interrupts. Interrupts sind in komplexeren Systemen nützlicher, die viele Dinge gleichzeitig ausführen (E / A, Zeitmessung, Zeitplanung usw.).

Wenn Sie mit der Endlosschleife arbeiten, ohne den Timer abzufragen oder die Zeit zu kalibrieren, die zum Ausführen einer Iteration der Schleife benötigt wird, müssen Sie auf Situationen achten, in denen das Hinzufügen von mehr Code in Ihrer Schleife das Timing und das Verhalten Ihres Steuerungssystems ändert.

Wenn Sie Ihren Steueralgorithmus in einem Timer-Interrupt implementieren, müssen Sie darauf achten, dass Sie nicht versuchen, mehr Arbeit auszuführen, als die CPU in einem Zeit- "Slot" verarbeiten kann, da dies wiederum das Verhalten Ihres Steuerungssystems beeinflusst.

Guy Sirton
quelle
4

Zusätzlich zu Guys Antwort erhöht die Verwendung eines Timer-Interrupts zur Erzeugung genauer Intervalle die Bestimmtheit.

Beispielsweise wissen Sie zu jedem Zeitpunkt genau, was der Prozessor tut, und alle Aktivitäten werden mit festgelegten Raten ausgeführt.

Sie sollten auch mit festgelegten Raten planen, da Sie sonst keine Grundlage für Zeitkonstanten und dergleichen haben, die für Ihre Filterung wesentlich sind.

Und schließlich bedeutet dies, dass die vorhandenen Aufgaben nicht verlangsamt werden, wenn Sie zusätzliche Aufgaben hinzufügen.


Eine einfache Abfrage ist in Ordnung, wenn dies alles ist, was Ihr System tun muss. Während die Planung von Zeitfenstern in einem trivialen System nur einen geringen Aufwand darstellt, ermöglicht das Hinzufügen von Anfang an Wachstum und Erweiterung, ohne dass später alles neu strukturiert werden muss.

Andrew
quelle
In einigen Situationen können Sie aus einer Schleife eine deterministischere Leistung erzielen als aus Interrupts. Bis zu einem Jitterzyklus. Wenn alles, was Sie tun, eine Sache ist ...
Guy Sirton
4

Ich möchte nur ein paar Punkte zu anderen Posts hinzufügen. Meine persönliche Meinung ist, dass eine endlose while-Schleife in Systemen, die von Snsoren lesen oder in Aktoren schreiben, keinen Sinn hat, da beide einige physikalische Einschränkungen haben, z. Es macht keinen Sinn, von Sensoren bei 1 MHz zu lesen, wenn der Sensor einen Stabilitätszyklus aufweist, bevor die Messung bei 100 Hz genau ist. Gleiches gilt für Autofahrer. Sie können 1-mil-Anweisungen zum Bewegen des Motors senden, aber es kann nur die physikalischen Einschränkungen in Bezug auf die Trägheit aushalten.

Was ich in meinen Entwürfen mache, folgt. Ich erstelle einen Timer-Interrupt, der etwa alle 1 ms ausgelöst wird, und dekrementiere dann einige globale Variablen in dieser Interrupt-Routine. In der Haupt-while-Schleife überprüfe ich, ob die Variable 0 ist, und führe einen Befehl aus, der von dieser Variablen definiert wird. In diesem Fall kann ich den Motor mit 125 Hz antreiben, den Sensor mit 20 Hz lesen und die LEDs mit 0,5 Hz ausgeben.

Ich hoffe du hast den Punkt verstanden.

Gossamer
quelle
3

Ich möchte auch betonen, dass der Vergleich zwischen Abfragen (dh Überprüfen, ob ein Interrupt-Flag gesetzt wurde) und Interrupt-Vektoren (dh einem ISR oder einer Funktion, die geladen wird, wenn ein Interrupt aufgetreten ist) mehr sein sollte als nur die Bewertung der Effizienz / Einfachheit der Ausführung eines Blocks reaktionären Codes. Die Interrupt-Controller der meisten modernen Mikros können so viel mehr, insbesondere wenn interperiphere Signale (dh DMA) in Betracht gezogen werden.

Mit einem Mikrocontroller TMS320F28335 von Texas Instruments können Sie beispielsweise den Start des Konvertierungsimpulses Ihres ADC direkt von der steigenden oder fallenden Flanke eines PWM auslösen . Darüber hinaus verfügt das Mikro über einen sechskanaligen DMA-Controller, der beispielsweise auch so programmiert werden kann, dass er dasselbe PWM-Signal auslöst (dies kann es Ihnen ermöglichen, einen Speicherlesevorgang über den Parallelbus der Geräte zu starten, das zum Beispiel an einen Hochgeschwindigkeits-Delta-Sigma-Wandler angeschlossen ist). Der gleiche DMA-Controller kann dann verwendet werden, um die vom ADC und vom externen Delta-Sigma gelesenen Werte in den internen RAM zu puffern. Der DMA-Controller kann dann so konfiguriert werden, dass er nur eine normale Interrupt-Serviceroutine auslöst, nachdem insgesamt 128 ADC- und Delta-Sigma-Messwerte abgetastet wurden. All dies würde ohne CPU-Eingriffe geschehen (Sie könnten andere Dinge tun).

Diese Art der Auslösung hinter den Kulissen ermöglicht es Ihnen, viel mehr Arbeit zu erledigen, als wenn ein ISR alle Aktivierungsflags oder Speicherlesevorgänge gesteuert hätte (aufgrund des mit der Interrupt-Latenz verbundenen Overheads ). Mit dem vektorkettigen Ansatz können Sie bei (sagen wir) 50 kHz abtasten, bei einem ISR-gesteuerten Ansatz können Sie nur bei (sagen wir) 5 kHz abtasten.

Wie Andrew sagte, ist die Verwendung von Interrupt-Vektoren viel deterministischer oder wiederholbarer als das Abfragen eines Statusregisters.

Ich würde auch empfehlen, Phil Koopmans Blog zu abonnieren oder zumindest die folgenden Beiträge zu lesen:

EDDY74
quelle
1

Alter Beitrag, der immer noch als Referenz für andere Personen antwortet.

Ich arbeite an einem ähnlichen Projekt. Sogar mir hatte ein Freund vorgeschlagen, einen Timer zu verwenden.

Schließlich würde ich vorschlagen, einen möglichst hohen Geschwindigkeitsregler zu verwenden (meiner ist 80 MHz). Verwenden Sie 5us Timer Interrupt (Scheduler). Führen Sie in dieser Scheduler-Interrupt-Routine die folgenden Schritte aus:

  1. CheckSensors ()
  2. ClockActuators () (Wenn Sie Stepper verwenden, stellen Sie zunächst alle Clk-Pins auf niedrig und dann auf Clk, je nachdem, welcher Motor laufen soll.)
  3. StateChange () / ApplicationRoutine () / SwitchContext () (weitere Informationen zu State Machine finden Sie unter: https://barrgroup.com/Embedded-Systems/How-To/State-Machines-Event-Driven-Systems ) (um ehrlich zu sein) , konnte den letzten Teil des Artikels nicht verdauen, kam aber auf die Idee. Ich verwende einen einfachen Switch Case in StateChange ().)

In der while (1) -Schleife von main ():

  1. Überprüfen Sie die Eingabe über Tastatur / Touchscreen / serielle Kommunikation usw.
  2. Anzeige aktualisieren (Wenn dies zu lang ist und die Reaktion der Tastatur langsam ist, versuchen Sie, den obigen Schritt auszuführen, z. B. Tastatur / Berührung / Seriell in Interrupt zu überprüfen.)
Krishnananda Hegde
quelle
Willkommen bei Robotics, Krishnananda Hegde. Es sieht so aus, als hätten Sie versehentlich zwei Konten erstellt (Krishnananda Hegde & Krishnananda. K. Hegde). Mit Stack Exchange kann nur eine Person ein Konto aktiv nutzen. Befolgen Sie daher die Anweisungen unter Ich habe versehentlich zwei Konten erstellt. Wie füge ich sie zusammen? Leider können Moderatoren keine Konten für Sie zusammenführen, aber möglicherweise Konten löschen, von denen sie glauben, dass sie Sockenpuppen sind .
Mark Booth
0

Die Verwendung von Polling oder Interrupt führt zwar zu keiner wesentlichen Änderung in einem einfachen Zeilenfolger-Roboter, aber es ist oft gut, Interrupts zu verwenden.

Obwohl Timer-Interrupts in einer Reihe von Fällen sehr gut verwendet werden, würde ich in diesem Fall vorschlagen, dass Sie besser einen einfachen Interrupt verwenden können, der ausgelöst wird, wenn eine bestimmte Eingabe vom Sensor kommt (z. B. weiße Farbe erkannt und Sensor gibt a logisch hoch). Auf diese Weise können Sie sicher sein, was genau Ihr Mikrocontroller tut, wenn er auf den weißen Fleck trifft. Es gibt auch die geringste Verzögerung zwischen dem Abrufen des Eingangs und dem Ausführen des entsprechenden Ausgangs.

Im Fall eines einfachen Zeilenfolgers können Sie jedoch einfach Interrupts belassen und mit der Abfrage fortfahren. Wenn Sie jedoch mit Ihrem Roboter Multitasking betreiben (z. B. mehrere Sensoren zum Betätigen verschiedener Dinge), benötigen Sie wahrscheinlich Interrupts. Ein weiterer Vorteil ist, dass Sie die Priorität für diese Ereignisse in Interrupts festlegen können. Zum Beispiel, was passieren würde, wenn Sie Aufgabe A ausführen und ein Interrupt kommt und nach Aufgabe B fragt. Sie können eine davon wichtiger machen, indem Sie eine davon auf eine höhere Priorität setzen. Auf diese Weise wird die Aktion mit höherer Priorität zuerst abgeschlossen.

Bhuvnesh
quelle