Dieses STM32 PWM Tutorial richtet sich an alle, die mit einem STM32-Mikrocontroller Motoren und LEDs nicht nur „ein- und ausschalten“, sondern wirklich präzise steuern möchten. PWM (Pulsweitenmodulation) ist dabei die zentrale Technik: Sie erlaubt es, die mittlere Leistung fein zu dosieren, ohne Energie in linearen Reglern zu verheizen. In der Praxis bedeutet das: LEDs dimmen gleichmäßig, DC-Motoren laufen kontrolliert an, Servos treffen definierte Positionen, und selbst Lüfter lassen sich leise und effizient regeln. STM32-Controller bieten hierfür leistungsfähige Timer mit mehreren Kanälen, Hardware-PWM, Dead-Time-Generatoren, Triggern für ADC/DMA und Sicherheitsfunktionen wie Break-Inputs. Dieses Tutorial führt verständlich durch die Grundlagen und zeigt anschließend typische Anwendungsfälle mit sauberer Hardware-Anbindung und klaren Konfigurationsschritten (CubeMX/HAL oder register-nah). Ziel ist, dass Sie am Ende nicht nur „irgendein PWM-Signal“ erzeugen, sondern Frequenz, Tastgrad, Auflösung und Timing sicher beherrschen und typische Stolpersteine vermeiden.
PWM-Grundlagen: Frequenz, Tastgrad und Auflösung
PWM beschreibt ein digitales Rechtecksignal, bei dem innerhalb einer festen Periodendauer T ein Anteil der Zeit auf „High“ liegt. Dieser Anteil ist der Tastgrad (Duty Cycle). Viele Lasten – insbesondere LEDs und Motoren – reagieren auf die mittlere Leistung. Je höher der Tastgrad, desto höher die mittlere Spannung beziehungsweise der mittlere Strom (bei geeigneter Beschaltung). Wichtig sind drei Kenngrößen: PWM-Frequenz, Tastgrad und die daraus resultierende Auflösung (wie fein der Tastgrad einstellbar ist).
Die mittlere Spannung am Ausgang (idealisiert) ergibt sich aus dem Tastgrad:
Der Tastgrad D ist das Verhältnis aus Einschaltzeit ton zur Periodendauer T:
Bei STM32 wird PWM in der Regel über Timer realisiert. Ein Timer zählt von 0 bis zum Auto-Reload-Register (ARR). Der Compare-Wert (CCR) bestimmt, wann der Ausgang umschaltet. Vereinfacht gilt:
Die PWM-Frequenz ergibt sich aus dem Timer-Takt und dem Prescaler (PSC):
Aus dieser Beziehung wird sofort klar: Hohe Frequenz bedeutet oft geringere Auflösung (kleineres ARR), und hohe Auflösung bedeutet oft niedrigere Frequenz. Für LEDs sind 500 Hz bis einige kHz üblich (um Flimmern zu vermeiden), für Motoren häufig 16–25 kHz (oberhalb des Hörbereichs), für Servos typischerweise 50 Hz mit Pulsbreiten von 1–2 ms.
Die richtige PWM-Frequenz für LEDs, DC-Motoren und Servos
Die Wahl der Frequenz ist nicht nur „Geschmackssache“, sondern hängt von Physik, Akustik und Elektronik ab. Eine zu niedrige LED-PWM kann sichtbares Flimmern verursachen oder bei Kameras Banding-Effekte erzeugen. Eine zu niedrige Motor-PWM kann den Motor hörbar „pfeifen“ lassen. Eine zu hohe Frequenz kann hingegen Schaltverluste erhöhen oder bei ungünstiger Beschaltung zu EMV-Problemen führen.
- LED-Dimmen: meist 500 Hz bis 4 kHz. Für Kameratauglichkeit eher höher (z. B. 2–10 kHz), abhängig vom Einsatz.
- DC-Motor/ Lüfter: häufig 16–25 kHz, um akustische Geräusche zu minimieren. Manche Treiber arbeiten bevorzugt in bestimmten Bereichen.
- Servo (RC-Standard): typischerweise 50 Hz (20 ms Periodendauer) mit 1–2 ms Pulsbreite. Moderne Servos können auch höhere Refresh-Raten unterstützen, aber 50 Hz ist ein sicherer Start.
Für Hintergrundwissen zur PWM und ihren Einsatzgebieten ist der Artikel zur Pulsweitenmodulation eine solide Orientierung. STM32-spezifische Details, insbesondere zu Timer-Funktionen, finden Sie in den offiziellen STM32-Ressourcen von STMicroelectronics sowie in den jeweiligen Reference Manuals und Datenblättern.
STM32-Timer verstehen: ARR, PSC, CCR und PWM-Modi
STM32-Timer sind vielseitig. Für PWM sind vor allem folgende Elemente entscheidend:
- Prescaler (PSC): teilt den Timer-Eingangstakt herunter. Größerer PSC → langsamerer Timer.
- Auto-Reload (ARR): definiert den Zählbereich und damit die Periodendauer.
- Capture/Compare (CCR1..CCR4): Schwellwert, bei dem der Ausgang umschaltet (Tastgrad).
- PWM Mode 1/2: bestimmt, ob der Ausgang „aktiv“ ist, solange CNT < CCR (Mode 1) oder umgekehrt (Mode 2).
- Preload: erlaubt „glattes“ Aktualisieren von ARR/CCR zum nächsten Update-Event, ohne Glitches.
Für Einsteiger ist ein robuster Standard: PWM Mode 1, Preload für CCR und ARR aktivieren, und Aktualisierungen nur über Update-Events übernehmen lassen. Damit vermeiden Sie kurze Fehlpulse, wenn Sie den Tastgrad im laufenden Betrieb ändern.
Auflösung praxisnah betrachten
Oft wird „16-Bit Timer“ mit „16-Bit PWM-Auflösung“ gleichgesetzt. In der Praxis hängt die Auflösung davon ab, wie groß ARR ist. Wenn ARR = 999, erhalten Sie 1000 Stufen (0–999), also etwa 10 Bit effektive Auflösung. Für LED-Dimmen reicht das häufig; für sehr feine Regelung oder Audio-PWM können höhere Stufenzahlen sinnvoll sein. Umgekehrt ist bei sehr hoher PWM-Frequenz das ARR zwangsläufig kleiner, wodurch die Schrittweite im Tastgrad gröber wird.
PWM mit STM32CubeMX/HAL konfigurieren
Viele Projekte starten mit STM32CubeMX (oder STM32CubeIDE). Der Ablauf ist meist ähnlich, unabhängig von der STM32-Familie:
- Timer auswählen (z. B. TIM2, TIM3, TIM1) und einen Kanal als „PWM Generation CHx“ konfigurieren.
- Passenden GPIO-Pin als Alternate Function (AF) zuweisen (CubeMX setzt das typischerweise automatisch).
- Prescaler und Counter Period (ARR) so wählen, dass die gewünschte Frequenz entsteht.
- PWM-Pulse (CCR) als Startwert setzen (z. B. 0% oder ein definierter Duty Cycle).
- Code generieren, Timer starten und Duty Cycle zur Laufzeit anpassen.
HAL-seitig sind typische Schritte: Timer initialisieren, PWM-Kanal starten und CCR schreiben. Entscheidend ist, dass Sie den richtigen Kanal verwenden und dass der Pin wirklich auf die korrekte Alternate Function gemappt ist. Bei Problemen lohnt ein Blick in die Pinout-Ansicht und ins Datenblatt (AF-Zuordnung).
Duty Cycle zur Laufzeit ändern, ohne Störungen
Für dynamische Regelung (z. B. Helligkeit oder Motorleistung) ändern Sie üblicherweise den CCR-Wert. Aktivieren Sie Preload, damit der neue Wert erst zum Update-Event wirksam wird. Dadurch vermeiden Sie Sprünge innerhalb einer Periode. Bei anspruchsvollen Anwendungen kann es zusätzlich sinnvoll sein, Updates zu synchronisieren (z. B. per Timer-Trigger) oder DMA zu nutzen, um eine ganze Sequenz von Duty-Cycle-Werten auszugeben.
LEDs präzise dimmen: Hardware, Strombegrenzung und Gamma-Korrektur
Beim Dimmen von LEDs ist ein häufiger Anfängerfehler, die LED direkt (ohne Strombegrenzung) an einen GPIO zu hängen. Verwenden Sie mindestens einen Vorwiderstand oder – bei höheren Leistungen – einen geeigneten LED-Treiber. PWM „ersetzt“ keine Strombegrenzung. Außerdem sollten Sie die maximalen GPIO-Ströme und die Gesamtstromlimits des Controllers beachten. Für mehrere LEDs oder hohe Ströme ist ein Transistor (NPN/MOSFET) oder ein dedizierter Treiber fast immer die bessere Wahl.
Ein weiterer Punkt: Das menschliche Auge nimmt Helligkeit nicht linear wahr. Wenn Sie den Duty Cycle linear von 0 bis 100% erhöhen, wirkt der Helligkeitsanstieg am unteren Ende oft zu grob und am oberen Ende zu fein. Hier hilft eine Gamma-Korrektur, also eine nichtlineare Zuordnung von „Helligkeitswert“ zu PWM-Duty.
- Einfach: Lookup-Tabelle (z. B. 256 Werte) für 8-Bit-Helligkeit auf 10–12 Bit PWM-Stufen.
- Flexibel: Berechnung per Potenzfunktion (je nach Performance), z. B. gamma ≈ 2.2.
- Professionell: Kombination aus Gamma und minimalem Duty Cycle, um LED-Dead-Zones (sehr kleine Ströme) zu kompensieren.
Wenn Sie LEDs in Anwendungen mit Kameras einsetzen (z. B. Maschinenvision), lohnt es sich, PWM-Frequenz und Kamera-Shutter abzustimmen. Eine höhere Frequenz reduziert Banding-Risiken, kann aber EMV und Schaltverluste erhöhen. Nutzen Sie kurze Leitungen, gute Masseführung und ggf. Serienwiderstände am Gate (bei MOSFET-Treibern), um Flanken zu kontrollieren.
DC-Motoren steuern: PWM, Treiberstufen und Schutzmaßnahmen
DC-Motoren sollten nicht direkt vom STM32-Pin betrieben werden. Sie benötigen eine Leistungsstufe, typischerweise eine H-Brücke oder einen Low-Side-/High-Side-MOSFET-Treiber. PWM kann entweder auf die Versorgung (Enable-Pin eines Treibers) oder auf die Steuersignale der Brücke gegeben werden – abhängig vom Treiberkonzept. Wichtig ist, dass Freilaufpfade (Body-Dioden bei MOSFETs oder dedizierte Dioden) und ein ausreichendes Layout vorhanden sind, damit die Induktionsenergie sicher abfließen kann.
- Freilauf/Recirculation: Induktive Lasten erzeugen Spannungsspitzen. Treiber und Dioden schützen die Schaltung.
- Entstörung: Kondensatoren am Motor (z. B. 100 nF direkt an den Bürsten) können Bürstenfeuer reduzieren.
- EMV: Hohe Flanken und lange Leitungen verstärken Störungen. Saubere Masseführung und Snubber können helfen.
- Strommessung: Shunt + ADC (getriggert vom Timer) ermöglicht echte Regelung und Überstromschutz.
Für eine leise Motoransteuerung wählen Sie häufig 20 kHz PWM. Prüfen Sie jedoch das Datenblatt Ihres Treibers: Manche Brücken sind für bestimmte Frequenzbereiche optimiert, und sehr hohe PWM-Frequenzen können die Treiber stärker erwärmen.
Sanftanlauf und Rampe
Statt den Tastgrad sprunghaft zu ändern, ist ein Rampe-Verlauf oft deutlich besser: Er reduziert Stromspitzen, schont Getriebe und verbessert das subjektive Laufverhalten. Technisch setzen Sie dazu eine Perioden-basierte Erhöhung des CCR-Werts um kleine Schritte. Für gleichmäßiges Verhalten ist es hilfreich, die Schrittweite und Schrittzeit so zu wählen, dass die Rampe unabhängig von der Timerfrequenz reproduzierbar bleibt.
Servos mit STM32 PWM ansteuern: Pulsbreite statt Duty Cycle
RC-Servos erwarten typischerweise eine Periode von 20 ms (50 Hz). Innerhalb dieser Periode kodiert die Pulsbreite die Position, häufig:
- ca. 1.0 ms: linker Anschlag
- ca. 1.5 ms: Mittelstellung
- ca. 2.0 ms: rechter Anschlag
In STM32-Timer-Begriffen bedeutet das: Sie setzen die PWM-Frequenz auf 50 Hz und variieren CCR so, dass die High-Zeit 1–2 ms beträgt. Wenn Ihr Timer beispielsweise auf 1 MHz getaktet ist (1 µs pro Tick), entspricht 20 ms einem ARR von 19999, und CCR liegt je nach Position zwischen 1000 und 2000. Diese „Pulsbreiten-PWM“ ist ein sehr anschauliches Beispiel dafür, warum es wichtig ist, nicht nur den Duty Cycle, sondern die absolute Zeitauflösung im Blick zu haben.
Fortgeschritten: Center-Aligned PWM, Dead Time und komplementäre Ausgänge
Für Leistungsanwendungen (z. B. BLDC/FOC, Halbbrücken, Schaltnetzteile) sind erweiterte Timer-Funktionen relevant. Viele STM32 bieten Advanced-Control-Timer (z. B. TIM1/TIM8) mit komplementären Ausgängen (CHx/CHxN), Dead-Time-Generator und Break-Input. Damit lassen sich zwei MOSFETs einer Halbbrücke so schalten, dass niemals beide gleichzeitig leiten (Shoot-Through). Dead Time fügt eine kurze „Sperrzeit“ zwischen dem Abschalten des einen und dem Einschalten des anderen Transistors ein.
- Center-Aligned PWM: reduziert bestimmte Spektralkomponenten und kann EMV verbessern, weil Schaltvorgänge symmetrisch zur Periodenmitte liegen.
- Komplementäre Ausgänge: ideal für Halbbrücken, wenn ein High-Side- und ein Low-Side-MOSFET getaktet werden.
- Dead Time: zwingend für Leistungselektronik, abhängig von MOSFET-Ladung und Treiber-Laufzeiten.
- Break-Input: Hardware-Sicherheitsabschaltung bei Fehlern (z. B. Überstromsignal).
Wer tiefer in Timer-Details einsteigen möchte, findet in den offiziellen Referenzhandbüchern und Application Notes von ST viele praxisnahe Hinweise; ein Einstiegspunkt ist die STM32 Education-Übersicht mit Lernmaterialien und Verweisen auf weiterführende Dokumente.
Typische Fehlerquellen und Debugging-Checkliste
Wenn PWM „nicht funktioniert“, liegt es oft nicht am Timer selbst, sondern an Randbedingungen. Diese kurze Checkliste spart meist viel Zeit:
- Pin-Mapping: Ist der GPIO wirklich auf die richtige Alternate Function (AF) gesetzt?
- Timer-Takt: Ist der Timer-Clock aktiviert? Stimmt der tatsächliche Takt (APB-Prescaler, Timer-Multiplikator)?
- ARR/PSC plausibel: Ergibt die Formel eine sinnvolle Frequenz? Ist ARR nicht versehentlich 0?
- Kanal gestartet: Wird der PWM-Kanal tatsächlich gestartet (und nicht nur der Basistimer)?
- Polarität/Mode: PWM Mode 1 vs. Mode 2, aktive Polarität passend zur Schaltung?
- Preload/Update: Werden CCR/ARR sofort oder erst beim Update-Event übernommen?
- Messung: Messen Sie mit Oszilloskop oder Logic-Analyzer direkt am Pin, nicht „irgendwo“ im Lastkreis.
Gerade bei Motor- und Leistungsanwendungen lohnt eine saubere Messkette: kurze Massefeder am Tastkopf, geeignete Bandbreite und – falls nötig – Differenzmessung. Viele Probleme wirken wie „Softwarefehler“, sind aber eigentlich Messartefakte oder Layout-Effekte.
Praxisrezept: Frequenz und Auflösung systematisch auswählen
Eine bewährte Vorgehensweise ist, zuerst die gewünschte PWM-Frequenz festzulegen (z. B. 20 kHz für Motoren), dann eine Zielauflösung abzuschätzen (z. B. mindestens 9–10 Bit für ruhige Regelung) und daraus die Timerparameter abzuleiten. Wenn die Kombination nicht passt, variieren Sie den Timer-Takt (sofern möglich), den Prescaler oder nutzen Sie einen anderen Timer. In manchen Fällen ist ein Advanced Timer mit höherem Eingangstakt oder besserer Funktionalität die sinnvollere Wahl.
Wenn Sie beispielsweise 20 kHz möchten, können Sie ARR so wählen, dass Sie eine ausreichende Anzahl Zählstufen erhalten. Je größer ARR, desto feiner die Duty-Schritte. Gleichzeitig muss die Formel für fPWM erfüllt bleiben. Mit dieser methodischen Sicht vermeiden Sie das typische „Trial-and-Error“ und erhalten reproduzierbare Ergebnisse – besonders wichtig, wenn später Regelalgorithmen, Filter oder Schutzfunktionen darauf aufbauen.
IoT-PCB-Design, Mikrocontroller-Programmierung & Firmware-Entwicklung
PCB Design • Arduino • Embedded Systems • Firmware
Ich biete professionelle Entwicklung von IoT-Hardware, einschließlich PCB-Design, Arduino- und Mikrocontroller-Programmierung sowie Firmware-Entwicklung. Die Lösungen werden zuverlässig, effizient und anwendungsorientiert umgesetzt – von der Konzeptphase bis zum funktionsfähigen Prototyp.
Diese Dienstleistung richtet sich an Unternehmen, Start-ups, Entwickler und Produktteams, die maßgeschneiderte Embedded- und IoT-Lösungen benötigen. Finden Sie mich auf Fiverr.
Leistungsumfang:
-
IoT-PCB-Design & Schaltplanerstellung
-
Leiterplattenlayout (mehrlagig, produktionstauglich)
-
Arduino- & Mikrocontroller-Programmierung (z. B. ESP32, STM32, ATmega)
-
Firmware-Entwicklung für Embedded Systems
-
Sensor- & Aktor-Integration
-
Kommunikation: Wi-Fi, Bluetooth, MQTT, I²C, SPI, UART
-
Optimierung für Leistung, Stabilität & Energieeffizienz
Lieferumfang:
-
Schaltpläne & PCB-Layouts
-
Gerber- & Produktionsdaten
-
Quellcode & Firmware
-
Dokumentation & Support zur Integration
Arbeitsweise:Strukturiert • Zuverlässig • Hardware-nah • Produktorientiert
CTA:
Planen Sie ein IoT- oder Embedded-System-Projekt?
Kontaktieren Sie mich gerne für eine technische Abstimmung oder ein unverbindliches Angebot. Finden Sie mich auf Fiverr.

