Der SystemTick in ARM C++

Den SysTick haben wir beim einfachen Programm bereits kennengelernt. Dieser stellt einen einfachen Zeitgeber für das Anwendungssystem dar. Standardmäßig ist der SysTick auf SystemCoreClock/100 konfiguriert. Damit verfügt unser System über ein vorgefertigtes 10 ms Ereignis.

Die Aufgabe

Diese Übung wird wiederum eine einfache Verwendung der SysTickFunction zur Generierung zyklischer Ausgaben demonstrieren. Wir lassen die LEDs auf dem Board unterschiedlich blinken. Das folgende Blockbild verdeutlicht, welche Bausteine bei dieser Aufgabe eine Rolle spielen. Vergleichen Sie diese vereinfachte Darstellung mit dem Blockbild aus dem Datenblatt.

Die vier LEDs auf dem STM32F4 Discovery sind immer noch fest mit den Pins D12 bis D15 verbunden. Der SystemTick soll so konfiguriert werden, dass dieses Ereignis alle 10 Millisekunden eintritt. Die Takt-Versorgung des GPIO Ports D erfolgt, wie wir wissen, über AHB1. Fassen wir die Aufgaben zusammen:

  1. Das SysTick-Ereignis auf 10 ms konfigurieren
  2. über den AHB1 Bus den GPIO Port D mit Takt versorgen
  3. die Bits 12 bis 15 des GPIO Port D als Ausgang konfigurieren
  4. wenn das SysTick-Ereignis eintritt, die LEDs an GPIO Port D12 bis D15 unterschiedlich blinken lassen

Vorbereitung

Falls Sie jetzt noch das Klassendiagramm geöffnet haben wählen Sie im Kontextmenü (rechte Maustaste) des Diagramms den Menüpunkt nach oben. Sollte das Projekt nicht mehr geöffnet sein, öffnen sie das SiSy UML-Projekt wieder. Legen Sie ein neues Klassendiagramm an, wählen Sie die Sprache ARM C++ und stellen Sie die Hardware (STM32F407) ein. Beim Öffnen des Diagramms (rechte Maustaste, nach unten) laden Sie aus dem SiSy LibStore die Diagrammvorlage Application Grundgerüst für PEC Anwendungen (XMC, STM32, AVR). Weisen Sie das Treiberpaket für STM32F4 zu.

Lösungsansatz

Die Aufgabe besteht darin die vier Led's anzusteuern. Folgen wir der objektorientierten Sichtweise sind die rote, blaue, grüne und orange LED Objekte und können über eine Klasse mit dem Namen Led abstrahiert werden. Die Klasse Led soll die spezifischen Merkmale (Struktur und Verhalten) von typischen LEDs auf der Anwenderebene abstrahieren. Also fragen wir uns was die vier LEDs denn aus Anwendersicht so tun sollen. Diese können an oder aus sein, sie können ihren Zustand wechseln, also umschalten. Tun die LEDs das zyklisch, blinken sie.

Schauen wir uns noch mal kurz die Systemarchitektur des Framework an. Unsere Klasse Controller hat alle Eigenschaften des PecAppKernel und dieser wiederum alle Merkmale eines PecAppModul.

Die Klasse Controller überschreibt die virtuellen Operationen onStart und onWork des PecAppModul. Es ist zu erkennen, dass der PecAppKernel bereits über einen SysTick-Ereignishandler verfügt. Diesen könnten wir überschreiben, um das SysTick-Ereignis zu empfangen. Schauen wir uns vorher aber noch mal das folgende Sequenzdiagramm an.

Der SysTick wird demzufolge an den PecAppKernel und alle PecAppModule verteilt. Dabei werden aus dem SysTick-Ereignis die Ereignisse für 10 Millisekunden, 100 Millisekunden und 1 Sekunde generiert.

Entwurf

Der erste grobe Entwurf den wir aus der Anwendersicht ableiten sieht in etwa so aus:

Die Abstraktion der Klasse Led hat bereits jemand für uns geleistet. Wir finden diese als vorbereitete Klasse in der Bibliothek. Wir können diese, wie bereits erprobt, nutzen. Dazu muss die Led aus dem Navigator bzw. Explorer per Drag&Drop in das Klassendiagramm gezogen werden.

Wenn wir die Led hereingezogen haben verbinden wir diese mit der Anwendung. Ziehen Sie von hier aus per Drag&Drop eine Verbindung von der Klasse Controller zur Klasse Led. Wählen Sie als Verbindungstyp die Aggregation und als Rollenbezeichner +led mit der Multiplizität 4. Die Anwendung hat jetzt vier Leds.

Wir wollen uns nicht direkt an den SysTick hängen, sondern an die aus demselben generierten Ereignisse für 10 und 100 Millisekunden sowie dem 1 Sekunden-Ereignis. Dazu überschreiben wir die Ereignishandler wie folgt:

  1. Ziehen Sie eine Operation aus der Objektbibliothek in die Klasse Contoller.
  2. Darauf hin öffnet sich der Dialog zum Einfügen von Operationen. Wählen Sie die Schaltfläche Weiter.
  3. Findet das Werkzeug Operationen, die sich überschreiben lassen bietet es diese zur Auswahl an.
  4. Wählen sie die Operation onTimer10ms.
  5. Bestätigen Sie Ihre Auswahl.

Wiederholen Sie diesen Vorgang für die Ereignisse onEvent100ms und onEvent1s. Danach sollte der Entwurf unserer Anwendung folgenden Entwicklungsstand erreicht haben.

Realisierung

Den Entwurf unterziehen wir einem kurzen Review. Dann können wir mit der Realisierung beginnen. Zuerst initialisieren wir die Geräte, sprich die LEDs. Diese sind mit GPIO-Ports D12 bis D15 verbunden. Die Initialisierung soll beim Start der Anwendung erfolgen.

Controller::onStart:

led[0].config(GPIOD,BIT12);
led[1].config(GPIOD,BIT13);
led[2].config(GPIOD,BIT14);
led[3].config(GPIOD,BIT15);
led[0].on();
led[1].on();
led[2].on();
led[3].on();

Die erste LED lassen wir aus der Mainloop heraus einen Blinkcode anzeigen.

Controller::onWork:

led[0].on();
waitMs(100);
led[0].off();
waitMs(100);
led[0].on();
waitMs(100);
led[0].off();
waitMs(400);

Die zweite LED soll alle 10 Millisekunden umschalten. Das ist auch noch verdammt schnell. mal sehen ob wir das noch wahrnehmen können ;-)

Controller::onTimer10ms:

led[1].toggle();

Bei 100 Millisekunden, also 10 mal Umschalten pro Sekunde, sollte sich das Blinken gut wahrnehmen lassen.

Controller::onEvent100ms:

led[2].toggle();

Ein mal pro Sekunde umschalten sind dann gemütliche 0,5 Hertz.

Controller::onEvent1s:

led[3].toggle();

Test

Erstellen, Übersetzen und Übertragen Sie das Programm. Die LEDs blinken jetzt in unterschiedlicher Geschwindigkeit.

Videozusammenfassung

Erlernte und gefestigte Arbeitsschritte:

  1. Klassendiagramm anlegen und öffnen
  2. Diagrammvorlage für PEC Applikation auswählen, laden und Treiberpaket für STM32F4 einfügen - Navigator auf UML Pakete umschalten
  3. gewünschte Klasse Led im Navigator/Explorer suchen und ins Diagramm ziehen
  4. Klasse aggregieren
  5. Operationen anlegen und in eine Klasse einfügen
  6. Operationen einer Basisklasse überschreiben
  7. den nötigen Quellcode in den Operationen erstellen
  8. Erstellen und Brennen eine ARM Anwendung im Klassendiagramm

Und hier diesen Abschnitt wiederum als Videozusammenfassung.

Übung

Erweitern Sie zur Übung die Anwendung derart, dass nur, wenn eine Taste gedrückt ist, die LEDs blinken.

Nächstes Thema

systemtickuml.txt · Last modified: 2019/02/04 14:10 (external edit)