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_dim [2020/01/06 18:00]
huwi [Test]
light_dim [2020/07/07 14:10] (aktuell)
huwi [Übung]
Zeile 1: Zeile 1:
 ====== Einen LED auf dem mySTM32 light Board dimmen ====== ====== Einen LED auf dem mySTM32 light Board dimmen ======
-...+{{tag>PWM DIMMEN LED}} 
 +Puls-Weiten-Modulation PWM ist eine wichtige Technik zum Erzeugen von Pseudo-AnalogwertenEs ist mit verhältnismäßig geringem Aufwand, zum Beispiel mit einem RC-Glied, auch möglich aus diesem Signal echte Analogwerte zu erzeugenMeist ist das jedoch gar nicht notwendig, wie wir an diesem Beispiel im wahrsten Sinne der Wortes **sehen** werden. Eigentlich müsste man sagen **nicht sehen** werden. Unser Auge wird nicht die einzelnen Impulse wahrnehmen aus denen das PWM-Signal besteht. Anwendung findet PWM nicht nur beim Ansteuern von LEDs sondern auch bei einfache Gleichstrommotoren, Schrittmotoren, Servomotoren, Wechselrichtern, Elektroheizungen, Magnetventilen, usw.. Die Liste der möglichen Anwendungsfälle ist recht lang. Deshalb haben auch alle modernen Mikrocontroller die Möglichkeit PWM-Signale mit Hardwarebausteinen generieren zu lassen. Prädestiniert für diese Aufgabe sind Timer
  
 ===== Die Aufgabe ===== ===== Die Aufgabe =====
-{{ :anwendersichtleddim.jpg?nolink&400|}}Es ist eine Mikrocontrolleranwendung zu entwickeln, bei der ... +{{ :anwendersichtleddim.jpg?nolink&400|}}Es ist eine Mikrocontrolleranwendung zu entwickeln, bei der eine LED für das menschliche Auge sanft auf und abblendet.
- +
-**Die Aufgabe lautet:**\\ //Der Anwender soll sehen, dass der Mikrocontroller funktioniert. Entwickeln Sie dafür eine Lösung die den Status des Mikrocontrollers durch blinken einer LED anzeigt. Diese StausLED soll an Port B0 angeschlossen werden.//+
  
 +**Anforderungen:**\\ 
 +  * die PWM-Frequenz muss flimmerfrei sein
 +  * das Auf- und Abblenden der LED soll gut wahrnehmbar sein
 +  * das Auf- und Abblenden kann auch nicht-liniear erfolgen
  
 ===== Vorbereitung ===== ===== Vorbereitung =====
Zeile 15: Zeile 18:
   * 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|}} 
- 
  
 ===== Lösungsansatz ===== ===== Lösungsansatz =====
-Die Aufgabe besteht darin ...+Die Aufgabe besteht darin eine LED für das menschliche Auge sanft Auf- und AbzublendenDazu soll ein entsprechendes PWM-Signal generiert werdenPWM ist kein analoges sondern ein digitales Signal in Form einer schnelle Folge von Impulsen mit unterschiedlicher Breiten. Jeder Impuls entspricht immer der vollen verfügbare Spannung in unserem Fall 3,3V die Pausen zwischen den Impulsen sind entsprechend 0V. Das Verhältnis zwischen High und Low ergibt die gewünschte Effektivspannung
  
-...+{{:pwm.png?nolink&1100|}}
  
-**__MERKE:__ Systembaustein xxx**\\ +In faktisch allen modernen Mikrocontrollern haben Timer die Fähigkeit ein oder mehrere PWM-Signale zu erzeugen. Dazu müssen die Entwickler der Hardware und Software sich über die möglichen Timer, PWM-Kanäle und Pinbelegungen im Datenblatt informieren. Hardware-PWM ist nicht an jedem beliebigen Pin möglich. Wir können dazu die [[http://shop.myavr.de/index.php?ws=download_file.ws.php&dlid=314&filename=produkte-mystm/mystm32-board-light/RK_mySTM32_light_de_en_2019-12.pdf|mySTM32 light Referenzkarte]] nutzen. 
 + 
 +{{::tim3ch3b0.png?nolink&700|}} 
 + 
 +Für das Pin B0 ergibt sich die Möglichkeit TIMER 3 Channel 3 zu nutzen. Im PEC Framework steht uns der Bibliotheksbaustein **PecPwmChannel** zur Verfügung. Dieser Baustein hat alle nötigen Merkmale um unsere LED zu dimmen. 
 + 
 +{{:stm32light:pecpwmchannel.png?direct&400|}} 
 + 
 +Damit ergibt sich folgender Grobentwurf.  
 + 
 +{{::controllerled.jpg?nolink&300|}}{{:stm32light:grobpwm.png?nolink&700|}} 
 + 
 +Die konkrete Hardwareanbindung Timer3, Channel3, PinB0 muss in der Realisierung erfolgen. 
 + 
 +{{:stm32light:t3c3b0.png?nolink&160|}} 
 + 
 + 
 +**__MERKE:__ PWM Timer + Channel + Pin**\\ 
  
  
 ===== Realisierung ===== ===== Realisierung =====
-Die Realisierung sollte die im obigen Entwurf beschriebenen Elemente beinhalten. Zusätzlich muss ...+Die Realisierung sollte die im obigen Entwurf beschriebenen Elemente beinhalten. Zusätzlich muss die konkrete Hardwareanbindung für Timer3, Channel3 und PinB0 erfolgenDazu suchen wir die entsprechenden Elemente im Explorer, ziehen diese per Drag&Drop ins Diagramm und verbinden sie mit der Led-Klasse **Pwm**Für das langsame also sanfte Auf- und Abblenden benötigen wir eine Variable als ZählerDiese legen wir als Attribut mit dem namen **duty** der Klasse **Controller** an. Da der Bibliotheksbaustein das PWM-Signal von 0 bis 1000 ansteuert benötigen wir mindestens einen 16 Bit Wert. Orientieren Sie sich an der folgenden Darstellung bei der Realisierung ihres Entwurfes: 
  
 {{:stm32light:stml011.png?direct&1000|}} {{:stm32light:stml011.png?direct&1000|}}
  
-...+In diesem Beispiel muss der Timer mit der gewünschten PWM Frequenz initialisiert und gestartet werdenDie PWM Frequenz sollte für das Auge nicht unter 60 Hz liegen, für das Ohr nicht unter 200 Hz (brummen von Endstufen bei echten Anwendungen) sollte aber auch nicht zu schell seinZu hohe Frequenzen können je nach Leitungslänge und angesteuertem Baustein zu ungewollte Effekte führen. Wir sollten also vermeiden zu weit in den Kilohertzbereich zu gehen. Ergänzen Sie den folgenden Code in der Operation **onStart()** der Klasse **Controller**.
  
-{{ :stm32light:stml008a.png?direct&300|}}+{{ :stm32light:stml011a.png?direct&300|}}
 >Controller::onStart():void <code c> >Controller::onStart():void <code c>
 // boot sequence after start SysTick // boot sequence after start SysTick
-pwm.configHz(10000); +// Initialisierung PWM Channel 
-pwm.setDuty(100);+// startet Timer mit gewünschter PWM Frequenz 
 +pwm.configHz(1000);
 </code> </code>
  
-...+Als erstes entwickeln wir eine einfache Lösung um das PWM Signal verhältnismäßig langsam ansteigen zu lassenDafür benutzen wir die Zählervariable **duty**Die Operation setDuty(duty) des Bibnliotheksbausteins **PecPwmChannel** erwartet Werte von 0 = LED aus bis 1000 LED maximale Helligkleit. Damit darf der Zähler entsprechend von 0 bis 1000 laufen. Mit einer kleinen Pause sorgen wir dafür, dass der Vorgang des langsamen Aufblendens auch wirklich langsam genug ist für das Auge.  Notieren Sie den folgenden Code in der Operation **onWork()** der Klasse **Controller**.
  
-{{ :stm32light:stml008b.png?direct&300|}}+{{ :stm32light:stml011b.png?direct&300|}}
 >Controller::onWork():void <code c> >Controller::onWork():void <code c>
-if(newDuty)+duty++; 
 +if (duty>=1000)
 { {
- newDuty = false; +    duty=0;
- pwm.setDuty(duty);+
 } }
 +pwm.setDuty(duty);
 +waitMs(1);
 </code> </code>
  
-{{ :stm32light:stml008b.png?direct&300|}} +===== Test ===== 
->Controller::onTimer10ms():void <code c> +Übersetzen Sie das Programm. Korrigieren Sie ggf. Schreibfehler. Übertragen Sie das lauffähige Programm in den Programmspeicher des Controllers. 
-duty+=dir+  - Rote LED mit Pin B0 verbinden 
-if(duty==0 || duty>=1000) +  - Anwendung erstellen (Kompilieren und Linken) 
- dir*=-1+  - Anwendung übertragen (Brennen) 
-newDuty=true;+  - Anwendung testen  
 + 
 +{{:erstellenbrennen.png?direct&350|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32bl1.png?direct&300|}} 
 + 
 +===== Lösungsvarianten ===== 
 +Die erste einfache Lösung hat folgenden Signalverlauf erzeugt: 
 + 
 +{{:stm32light:saegezahn.png?direct&600|}} 
 + 
 +Man kann mit diesem Signal schon recht gut das Aufblenden der LED erkennen aber wirklich schön ist es nicht. Die nächste Lösung soll auch das langsame Abblenden der LED verwirklichen. Dazu müssen wir den folgenden Signalverlauf erzeugen: 
 + 
 +{{:stm32light:dreieck.png?direct&600|}} 
 + 
 +Der Zähler muss also so angewendet werden, dass nach dem steigenden auch der fallende Signalverlauf folgt.\\  Ändern Sie den Code der Operation **onWork()** der Klasse **Controller** wie folgt: 
 +  
 +{{ :stm32light:stml011c.png?direct&300|}} 
 +>Controller::onWork():void <code c> 
 +duty++
 +if (duty<1000) { 
 +    pwm.setDuty(duty); 
 +
 +else if (duty<2000) { 
 +    pwm.setDuty(2000-duty)
 +
 +else { 
 +    duty=0; 
 +
 +waitMs(1);
 </code> </code>
  
-...+Erstellen, übertragen und testen Sie diese Anwendungsvariante.\\  
 +Man kann jetzt deutlich das Auf- und Abblenden der LED erkennen
  
-...+Aber auch dieser Signalverlauf erscheint unserem Auge noch nicht wirklich angenehmDas liegt daran, dass wir die Helligkeit nicht linear wahrnehmenDas Auge nimmt kleine Änderungen der Helligkeit im unteren Bereich recht gut wahrAb spätestens 50% können wir kaum noch die Änderung der Helligkeit erkennen. Eine Lösung ist es den Signalverlauf nicht linear sondern exponentiell zu gestalten. Das könnte zum Beispiel so aussehen:
  
-===== Test ===== +{{:stm32light:exponentiell.png?direct&700|}} 
-Übersetzen Sie das ProgrammKorrigieren Sie ggfSchreibfehlerÜbertragen Sie das lauffähige Programm in den Programmspeicher des Controllers+ 
-  - Erstellen (Kompilieren und Linken+Mit der Formel **POTENZ(X,Y)** kann man in Excel den gewünschten Signalverlauf in 1000 Schritten gut experimentell ermittelnMan kommt in etwa zu dem Ergebnis **POTENZ(1,00693;Step)**Die entsprechende C/C++ Funktion ist **pow(x,y)** und findet sich in der **#include "math.h"**. Dazu muss ein entsprechender Eintrag in der Klasse **Controller** vorgenommen werden. Selektieren Sie die Klasse **Controller** und wählen im Kontextmenü (rechte Maustaste) den Menüpunkt **Definieren...**. Im Dialog **Deklarationen/Implementation** ergänzen sie bitte folgende Zeile: 
-  Brennen + 
-  verbinden Sie ...+{{:stm32light:math.png?direct&400|}} 
 + 
 +Jetzt können wir die Funktion **pow(x,y)** aus der **math.h** anwenden.\\  
 +Ändern Sie Code der Operation **onWork()** der Klasse **Controller** wie folgt: 
 + 
 +>Controller::onWork():void <code c> 
 +//--------------------------------------------------------------
 +// atmende LED mit Exponentialfunktion pwm 0-1000 #include math.h 
 +duty++; 
 +if      (duty<1000) pwm.setDuty( pow(1.00693,duty) ); 
 +else if (duty<2000) pwm.setDuty( pow(1.00693,2000-duty) ); 
 +else                duty=0; 
 +waitMs(1); 
 +</code> 
 + 
 +Erstellen, übertragen und testen Sie diese Anwendungsvariante.\\  
 +Man kann jetzt deutlich das sanfte Auf- und Abblenden der LED erkennenDie LED scheint regelrecht zu atmen.
  
-{{:erstellenbrennen.png?direct&350|}}{{:stm32light:flashlight.png?direct&300|}}{{:stm32light:stm32bl1.png?direct&300|}} 
  
 ====== Videozusammenfassung ====== ====== Videozusammenfassung ======
 +{{tag>Video}}
 Erlernte und gefestigte Arbeitsschritte: Erlernte und gefestigte Arbeitsschritte:
-  - ... 
  
-====== Übung ====== +  - Klassendiagramm anlegen und öffnen 
-Erweitern Sie zur Übung die Anwendung um ...+  - Diagrammvorlage für PEC Applikation auswählen, laden und Treiberpaket für STM32F0 einfügen 
 +  - gewünschte Bausteine im Explorer/Navigator suchen und ins Diagramm ziehen 
 +  - Klassen aggregieren 
 +  - Attribute und Operationen einer Klasse anlegen 
 +  - Klassen und Templates zu Komponenten zusammenbauen 
 +  - den nötigen Quellcode in den Operationen erstellen 
 +  - Erstellen und Brennen einer ARM Applikation im Klassendiagramm 
 +  - das SiSy-ControlCenter konfigurieren und anwenden 
 + 
 +Und hier diesen Abschnitt wiederum als Videozusammenfassung. 
 + 
 +<html> 
 +<iframe width="1030" height="580" src="https://www.youtube.com/embed/b_YX8wC4IVU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> 
 +</html> 
 + 
 +[[https://youtu.be/I-3D3XcPBuw|oder die schnelle Version ohne Sprachkommentare]] 
 + 
 + 
 +====== Übung ====== 
 +Erweitern Sie zur Übung die Anwendung um eine UART-Verbindung mit 19200 BAUD zum SiSy-ControlCenterSenden sie die PWM-Werte für die Ansteuerung der LED als 8 Bit Zahlen an das SiSy-ControlCenterVerfolgen Sie den Signalverlauf in der Oszi-Ansicht des ControlCenters. 
 + 
 +{{:stm32light:ccsignalverlauf.png?direct&800|}}
  
 ====== Weiter mit: ====== ====== Weiter mit: ======
   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]   * [[mystm32_board_light_tutorial|zurück zur Übersicht]]
-  * [[extrene Interrupts mit dem mySTM32 light]]+  * [[einen Timer mit dem mySTM32 light benutzen]] 
 + 
 +====== Suchbegriffe ======