Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
light_systemtickuml [2020/01/06 14:40]
huwi [Videozusammenfassung]
light_systemtickuml [2020/07/23 11:50] (aktuell)
huwi [Erweiterung]
Zeile 1: Zeile 1:
 ====== Der SystemTick ====== ====== Der SystemTick ======
 +{{tag>SysTick LED BLINKY}}
 ARM Controller sind mit ihrer Leistungsfähigkeit prädestiniert für den Einsatz entsprechender Laufzeitumgebungen oder geeigneter Echtzeitbetriebssysteme. Solche basieren meist auf einer Timer-getriggerten Verteilung von Ressourcen, vor allem der Ressource Rechenzeit. Dafür steht beim ARM ein spezieller Timer zur Verfügung, der ausschließlich die Aufgabe hat, ein System-Trigger-Ereignis zu generieren.  ARM Controller sind mit ihrer Leistungsfähigkeit prädestiniert für den Einsatz entsprechender Laufzeitumgebungen oder geeigneter Echtzeitbetriebssysteme. Solche basieren meist auf einer Timer-getriggerten Verteilung von Ressourcen, vor allem der Ressource Rechenzeit. Dafür steht beim ARM ein spezieller Timer zur Verfügung, der ausschließlich die Aufgabe hat, ein System-Trigger-Ereignis zu generieren. 
  
Zeile 23: Zeile 24:
   * Diagrammvorlage //Application Grundgerüst für PEC Anwendungen (XMC, STM32, AVR)// laden   * Diagrammvorlage //Application Grundgerüst für PEC Anwendungen (XMC, STM32, AVR)// laden
   * Treiberpaket für //STM32F0// zuweisen   * Treiberpaket für //STM32F0// zuweisen
-  * optional Template //stm32F042_48Mhz// zuweisem+  * optional Template //stm32F042_48Mhz// zuweisen
  
 {{:neueskldhallo.jpg?direct&290|}}{{:pecapplication.jpg?direct&250|}}{{:stm32light:stml001.png?direct&450|}}  {{:neueskldhallo.jpg?direct&290|}}{{:pecapplication.jpg?direct&250|}}{{:stm32light:stml001.png?direct&450|}} 
Zeile 31: Zeile 32:
 Die Aufgabe besteht darin in geeigneter Form das Konzept des System-Timers mit den daraus folgenden Systemereignissen zu demonstrieren. Als Rückmeldung für den Anwender benutzen wir optische Signale, das sind blinkende LEDs und ein akustisches Signal, das ist der Speaker. Die Aufgabe besteht darin in geeigneter Form das Konzept des System-Timers mit den daraus folgenden Systemereignissen zu demonstrieren. Als Rückmeldung für den Anwender benutzen wir optische Signale, das sind blinkende LEDs und ein akustisches Signal, das ist der Speaker.
  
-Zunächst zum **10 Millisekunden** Ereignis. Dieses Ereignis wird direkt aus der Interruptfunktion (Interrupt Servive Routine oder auch Interrupt Handler) aufgerufen. Für den Anwendungsentwickler bedeutet das diese Funktion nur im Ausnahmefall und wenn dann nur mit sehr wenig also schnellem Code zu benutzen, da wir sonst das System ausbremsen. Dass es sich um ein Ereignis handelt erkennen wir an dem Präfix **on** bei der Operation **onTimer10ms()**. Die 10 Millisekunden sind viel zu schnell um es als blinkende LED wahrzunehmen. Deshalb legen wir das Signal auf den Speaker denn hören können wir Frequenzen bis weit in den Kilohertzbereich.+Zunächst zum **10 Millisekunden** Ereignis. Dieses Ereignis wird direkt aus der Interruptfunktion (Interrupt Service Routine oder auch Interrupt Handler) aufgerufen. Für den Anwendungsentwickler bedeutet das diese Funktion nur im Ausnahmefall und wenn dann nur mit sehr wenig also schnellem Code zu benutzen, da wir sonst das System ausbremsen. Dass es sich um ein Ereignis handelt erkennen wir an dem Präfix **on** bei der Operation **onTimer10ms()**. Die 10 Millisekunden sind viel zu schnell um es als blinkende LED wahrzunehmen. Deshalb legen wir das Signal auf den Speaker denn hören können wir Frequenzen bis weit in den Kilohertz-Bereich.
  
 {{::smdspeaker.jpg?nolink&110|}} {{:uml:classspk.png?nolink&110|}} {{::smdspeaker.jpg?nolink&110|}} {{:uml:classspk.png?nolink&110|}}
  
-Das Ereignis für die **100 Millisekunden** wird nicht direkt aus der Interupptfunktion aufgerufen sondern geht den Weg über eine Ereigniswarteschlange (Event Queue). Das bedeutet, dass Ereignisse sich ihrer Reihenfolge nach in der Warteschlange anstellen und wenn das System genug Zeit hat werden diese abgearbeitet. Das führt zwar dazu, dass einige Mikrosekunden Verzögerung (Latenzzeit) zwischen dem Auftreten des Ereignisses und dem Abarbeiten der Ereignisreaktion liegen aber dafür kann das System die dafür aufgewendete Prozessorzeit viel besser managen und das System läuft trotzdem flüssig. Wir erkennen diesen Sachverhalt an dem Bezeichner **Event** im Ereignisnamen **onEvent100ms()**. Hier können wir beruhigt eine LED anschließen. Die 100 Millisekunden zwischen jedem Umschalten ergeben 5 Hertz, das nehmen wir locker als blinken wahr. +Das Ereignis für die **100 Millisekunden** wird nicht direkt aus der Interruptfunktion aufgerufen sondern geht den Weg über eine Ereigniswarteschlange (Event Queue). Das bedeutet, dass Ereignisse sich ihrer Reihenfolge nach in der Warteschlange anstellen und wenn das System genug Zeit hat werden diese abgearbeitet. Das führt zwar dazu, dass einige Mikrosekunden Verzögerung (Latenzzeit) zwischen dem Auftreten des Ereignisses und dem Abarbeiten der Ereignisreaktion liegen aber dafür kann das System die dafür aufgewendete Prozessorzeit viel besser managen und das System läuft trotzdem flüssig. Wir erkennen diesen Sachverhalt an dem Bezeichner **Event** im Ereignisnamen **onEvent100ms()**. Hier können wir beruhigt eine LED anschließen. Die 100 Millisekunden zwischen jedem Umschalten ergeben 5 Hertz, das nehmen wir locker als blinken wahr. 
  
 {{:LEDrot.jpg?nolink&110|}} {{:uml:classred.png?nolink&110|}} {{:LEDrot.jpg?nolink&110|}} {{:uml:classred.png?nolink&110|}}
Zeile 53: Zeile 54:
 {{:uml:klassecontroller.jpg?nolink&110|}} {{:uml:classgreen.png?nolink&110|}} {{:uml:classyellow.png?nolink&110|}} {{:uml:classred.png?nolink&110|}} {{:uml:classspk.png?nolink&110|}} {{:uml:klassecontroller.jpg?nolink&110|}} {{:uml:classgreen.png?nolink&110|}} {{:uml:classyellow.png?nolink&110|}} {{:uml:classred.png?nolink&110|}} {{:uml:classspk.png?nolink&110|}}
  
-Diese müssen wieder in Beziehung gesetzt werden. Für die gestellten Anforderungen (toggle) reicht als Bibliotheksbaustein **PecPinOutput** völlig aus. Der Grobentwurf sieht dann so aus:+Diese müssen wieder in Beziehung gesetzt werden. Für die gestellten Anforderungen (toggle) reicht als Bibliothek Baustein **PecPinOutput** völlig aus. Der Grobentwurf sieht dann so aus:
  
 {{:stm32light:stml005aaa.png?nolink&600|}} {{:stm32light:stml005aaa.png?nolink&600|}}
Zeile 74: Zeile 75:
 {{:stm32light:step11.png?direct&1100|}} {{:stm32light:step11.png?direct&1100|}}
  
-Im nächsten Schritt hängen wir uns an die Systemereignisse für 10, 100 und 1000 Millisekunden indem wir jeweils **Operationen** auf die Klasse **Controller** ziehen und Schritt für Schritt folgende Ereignishandler einfügen:+Im nächsten Schritt hängen wir uns an die Systemereignisse für 10, 100 und 1000 Millisekunden indem wir jeweils **Operationen** auf die Klasse **Controller** ziehen und Schritt für Schritt folgende Funktionen zur Ereignisbehandlung einfügen:
   * onTimer10ms()   * onTimer10ms()
   * onEvent100ms()   * onEvent100ms()
Zeile 85: Zeile 86:
 {{:stm32light:stml005.png?direct&800|}} {{:stm32light:stml005.png?direct&800|}}
  
-für die realisierung der geforderten Funktionalität ergänzen wir die folgenden Codes in den jeweiligen Ereignisfunktionen. Zuerst lassen wir in **onWork** die gelbe LED dimmen. +für die Realisierung der geforderten Funktionalität ergänzen wir die folgenden Codes in den jeweiligen Ereignisfunktionen. Zuerst lassen wir die rote LED blinkenDazu stuern wir im 100 Millisekunden Ereignis die rote LED wie folgt an.
- +
-{{ :stm32light:stml005a.png?direct&300|}} +
->Controller::onWork():void <code c> +
-static uint16_t dim=0; +
- +
-if (dim < 1000) +
-+
- yellowLED.on(); +
- waitUs(dim); +
- yellowLED.off(); +
- waitUs(1000-dim); +
- dim++; +
-+
-else if (dim <2000) +
-+
- yellowLED.on(); +
- waitUs(2000-dim); +
- yellowLED.off(); +
- waitUs(dim-1000); +
- dim++; +
-+
-else +
-+
- dim=0; +
-+
-</code> +
- +
-Im 100 Milisekunden Ereignis steuern wir die rote LED an.+
  
 {{ :stm32light:stml005c.png?direct&200|}} {{ :stm32light:stml005c.png?direct&200|}}
Zeile 143: Zeile 116:
  
 {{:erstellenbrennen.png?direct&350|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32bl3.png?direct&300|}} {{:erstellenbrennen.png?direct&350|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32bl3.png?direct&300|}}
 +
 +===== Erweiterung =====
 +Als nächstes erweitern wir die Anwendung so, dass wir das Ereignis **onWork()** welches fortlaufend aus der //Mainloop// der Laufzeitumgebung des Frameworks getriggert wird, benutzen um die gelbe LED ganz schwach glimmen zu lassen (dimmen). Dabei soll das sicht- und hörbare Laufzeitverhalten der anderen Ausgabegeräte nicht beeinflusst werden. Deshalb verwenden wir **keine** langen Wartefunktionen wie **waitMs()**.
 +
 +{{ :stm32light:simpledim.png?200|}}
 +>Controller::onWork():void <code c>
 +// continuous event from the Mainloop
 +uint8_t brightness=1; // use here 1 to 255 for fix brightness of the yellow LED
 +yellowLED.on();
 +for (int i=brightness; i>0; i--);
 +yellowLED.off();
 +for (int i=255-brightness; i>0; i--);
 +</code> 
 +
 +Erstellen, Übertragen und testen Sie diese Erweiterung. Experimentieren Sie mit verschiedenen Werten der Variablen **brightness** (1-255); 
 +
 +===== Variante =====
 +Das Dimmen der gelben LED können wir noch erweitern indem die LED selbständig auf und abblendet. Probieren Sie die folgende Variante. Sie werden Feststellen, dass auch diese recht komplexe Lösung das Laufzeitverhalten der anderen LEDs und des Speakers nicht spürbar beeinflussen.
 +
 +{{ :stm32light:stml005a.png?direct&300|}}
 +>Controller::onWork():void <code c>
 +static uint16_t dim=0;
 +
 +if (dim < 1000)
 +{
 + yellowLED.on();
 + waitUs(dim);
 + yellowLED.off();
 + waitUs(1000-dim);
 + dim++;
 +}
 +else if (dim <2000)
 +{
 + yellowLED.on();
 + waitUs(2000-dim);
 + yellowLED.off();
 + waitUs(dim-1000);
 + dim++;
 +}
 +else
 +{
 + dim=0;
 +}
 +</code>
 +
 +Vertiefen sie die Bedeutung des Schlüsselwortes **static** in C/C++ und warum dieses Schlüsselwort bei der obigen Lösung verwendet wurde. 
  
 ====== Videozusammenfassung ====== ====== Videozusammenfassung ======
 Erlernte und gefestigte Arbeitsschritte: Erlernte und gefestigte Arbeitsschritte:
 +{{tag>Video}}
   - Klassendiagramm anlegen und öffnen   - Klassendiagramm anlegen und öffnen
   - Diagrammvorlage für PEC Applikation auswählen, laden und Treiberpaket für STM32F4 einfügen   - Diagrammvorlage für PEC Applikation auswählen, laden und Treiberpaket für STM32F4 einfügen
   - Navigator auf UML Pakete umschalten   - Navigator auf UML Pakete umschalten
-  - gewünschte Klasse Led im Navigator/Explorer suchen und ins Diagramm ziehen+  - gewünschte Klasse LED im Navigator/Explorer suchen und ins Diagramm ziehen
   - Klasse aggregieren   - Klasse aggregieren
   - **Operationen anlegen und in eine Klasse einfügen**   - **Operationen anlegen und in eine Klasse einfügen**
Zeile 159: Zeile 178:
 Und hier diesen Abschnitt wiederum als Videozusammenfassung. Und hier diesen Abschnitt wiederum als Videozusammenfassung.
  
-<<<< ACHTUNG VERALTETES VIDEO >>>>+<html> <iframe width="1030" height="580" src="https://www.youtube.com/embed/W9Ge36El-pE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe</html>
  
-<html><iframe width="640" height="400" src="https://www.youtube.com/embed/QHxU48vDHCI" frameborder="0" allowfullscreen></iframe></html>+[[https://youtu.be/aDVGJbOlALY|oder die schnelle Version ohne Sprachkommentare]]
  
-====== Übung ======+====== Übung ======
 Ändern Sie zur Übung die Anwendung wie folgt: Ändern Sie zur Übung die Anwendung wie folgt:
-  - Änderung: Kommentieren Sie den Code in **onTimer10ms** aus und lassen den Speaker in **onWork** toggeln.\\ Bilden und Testen Sie diese geänderte Anwednung.\\ Vergleichen und bewerten Sie das akustische Ergebnis. +  - Änderung: Kommentieren Sie den Code in **onTimer10ms** aus und lassen den Speaker in **onWork** toggeln.\\ Bilden und Testen Sie diese geänderte Anwendung.\\ Vergleichen und bewerten Sie das akustische Ergebnis. 
     - Der Ton ist viel höher. Was bedeutet das?     - Der Ton ist viel höher. Was bedeutet das?
     - Der Ton hat ist nicht durchgehend sondern hat Störungen. Warum?     - Der Ton hat ist nicht durchgehend sondern hat Störungen. Warum?
-  - Änderung: Fügen Sie in **onWork** mit **waitMs** eine Wartetzeit von 500 ms ein.\\ Bilden und Testen Sie diese geänderte Anwednung.\\ Vergleichen und bewerten Sie das  optische und akustische Ergebnis.+  - Änderung: Fügen Sie in **onWork** mit **waitMs** eine Wartezeit von 500 ms ein.\\ Bilden und Testen Sie diese geänderte Anwendung.\\ Vergleichen und bewerten Sie das  optische und akustische Ergebnis.
     - Der Ton ist nur noch ein Knacksen.      - Der Ton ist nur noch ein Knacksen. 
     - Das Timing der Blinkenden LEDs hat sich verändert.     - Das Timing der Blinkenden LEDs hat sich verändert.
Zeile 176: Zeile 195:
   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]
   * [[light UASRT|Kommunikation des mySTM32 light mit dem PC]]   * [[light UASRT|Kommunikation des mySTM32 light mit dem PC]]
 +
 +====== Suchbegriffe ======