Externe Interrupts mit dem MM32 auswerten
In der vorausgegangenen Übung haben wir einen Timer als internen Trigger genutzt. Bei eingebetteten Systemen ist kommt externen Auslösern jedoch mindest die selbe Bedeutung zu wie die Nutzung von Timern. Beispiele lassen sich endlos aufzählen, in einem Auto finden wir Schalter als Auslöser für Systemaktionen an allen Türen, der Heck- oder Kofferaumklappe, den Sicherheitsgurten, dem Beleuchtungssystem, Fensterheber, jede Menge Schalter für den Fahrer im Cockpitbereich und am Lenkrad usw. usw. All diese Schaltelemente schalten längst nicht mehr plump irgendetwas ein oder aus. Die Signale von diesen Systembausteinen werden von Mikrocontrollern verarbeitet. Das könnte man natürlich durch ständiges Abfragen (polling) der Schalter tun. Bei der großen Anzahl von auszuwertenden Signalen kann das doch schon erheblich Rechenzeit fressen die dann für andere Aufgaben nicht zur Verfügung steht. Damit kommt dem erkennen von Änderungen (steigende oder fallende Flanken) an den Signaleingängen und dem Auslösen und Verarbeiten von Hardware-Ereignissen also Interrupts große Bedeutung zu, denn ereignisorientierte Verarbeitung verbraucht signifikant weniger Rechenzeit und kann zusätzlich noch viel besser Prioritäten der Signal beachten.
Die Aufgabe
Es ist eine Mikrocontrolleranwendung zu entwickeln, bei der eine Externes Signal, fallende Flanke, als Auslöser einer Aktivität des Controllers dient. Die Reaktion des Controllers auf das externe Ereigniss soll durch das Umschalten einer LED realisiert werden.
Die Lösung soll folgende Anforderungen erfüllen:
- Externes Signal, fallende Flanke, durch Taster an A0
- LED-Anzeige an Pin B0
- Kein ständiges Abfragen des Tasters (polling)
- Behandlung des Ereignisses direkt im Interrupt
Vorbereitung
Führen Sie folgende Vorbereitungsarbeiten durch:
- neues Klassendiagramm anlegen
- Zielsprache ARM C++
- Zielplattform MM32L073 myMM32 Board light
- Diagrammvorlage Application Grundgerüst für PEC Anwendungen (XMC, STM32, AVR) laden
- Treiberpaket für MM32L0 zuweisen
Lösungsansatz
Die Aufgabe besteht darin das Betätigen der Funktionstaste per Interrupt auszuwerten. Als Reaktion auf den Interrupt soll die AnzeigeLED umschalten. Die PEC-Bibliothek bietet für die Aufgabe externe Interrupts zu behandeln den Bibliotheksbaustein PecPinInterrupt.
Schaut man sich diesen Baustein näher an ist Festzustellen, dass PecPinInterrupt alle Eigenschaften von PecPinInput besitzt und wie dieser zum beispiel mit pinPullUp und pinLowActive kombiniert werden kann. Diese Optionen sind für die Taster auf dem myMM32 Board light gut geeignet da diese beim Betätigen gegen Masse schließen.
Für die Anzeige-LED können wir PecPinOutput oder PecLed nutzen. Die Handhabung dieser Bausteine ist uns inzwischen vertraut. Aus diesen Betrachtungen lässt sich der folgender Grobentwurf ableiten.
Dieses Klassenmodell lässt sich wie folgt textuell beschreiben:
Der Controller hat eine Funktionstaste. Die Funktionstaste ist ein PecPinInterrupt. Die Funktionstaste hat eine IndicatorLED. Die IndicatorLED ist eine PecLed.
Neu an diesem Entwurf ist, dass die Klasse IndicatorLED nicht in den Controller sondern an die Klasse FunctionKey aggregiert wurde. Damit wurde eine Struktur aufgebaut bei der die Klasse FunktionKey die Klasse IndicatorLED sozusagen in sich versteckt. Sonst hatten wir Systembausteine immer an den Controller gehängt. Die neue Lösung hat den Vorteil, dass beim ansprechen der LED nicht der Pfad über die Instanz des Controllers gegangen werden muss. Da die Klasse FunctionKey jetzt der Eigentümer der IndicatorLED ist kann diese ohne Einschränkungen direkt benutzt werden. Das Macht auch Sinn. Kein anderer Baustein in dieser Anwendung benutzt die IndicatorLED. FunctionKey und IndicatorLED bilden jetzt eine zusammengesetzte Einheit die vom Controller als ein Baustein benutzt wird. Zusammengesetzte Systembausteine nennt man Systemkomponente.
MERKE: Systemkomponente = Aggregation aus mehreren Systembausteinen
Realisierung
Die Realisierung sollte die im obigen Entwurf beschriebenen Elemente beinhalten. Zusätzlich müssen folgende Modellelemente ergänzt werden.
- die konkreten Pins A0 und B0 für den Taster und die LED
- pinLowActive und piPullUp für den Taster
- virtuelle Operation onPinInterrupt() der Klasse FunctionKey überschreiben
orientieren Sie sich bei der Realisierung der nötigen Arbeitsschritte an der obigen Darstellung.
Die geforderte Reaktion auf das Betätigen der Taste (Signaländerung: fallende Flanke) soll im Interrupt erfolgen also in der Operation onPinInterrupt(). Notieren sie dort den Code zum toggeln der LED.
FunctionKey::onPinInterrupt():voidindicatorLED.toggle();
Die Operationen onStart() und onWork der Klasse Controller bleiben leer. Alles Aktionen erfolgen im Interrupt. Erstellen und Testen Sie diese Anwendung.
Test
Übersetzen Sie das Programm. Korrigieren Sie ggf. Schreibfehler. Übertragen Sie das lauffähige Programm in den Programmspeicher des Controllers.
- Erstellen (Kompilieren und Linken)
- Brennen
- verbinden Sie …
Videozusammenfassung
Erlernte und gefestigte Arbeitsschritte:
- Klassendiagramm anlegen und öffnen
- Diagrammvorlage für PEC Applikation auswählen, laden und Treiberpaket für MM32L0 einfügen
- im Explorer PEC-Bausteine aus der Bibliothek suchen
- gewünschte Bibliotheksbausteine und ins Diagramm ziehen
- Klassen verbinden (Aggregation, Realisierung)
- Komponenten aus Systembausteinen zusammensetzen
- den nötigen Quellcode in den Operationen erstellen
- Erstellen und Brennen einer MM32 Applikation im Klassendiagramm
Und weil es so schön war hier das Ganze noch mal als Video.
Übung
Erweitern Sie die Anwendung um eine Zweite Taste mit einem UART-Terminal. Bei jedem Tastendruck soll ein Zähler hochgezählt werden und mit 19200 Baud an das SiSy-Controlcenter gesendet werden.