Forum: Mikrocontroller und Digitale Elektronik STM32 Timer (PWM)


von Anne J. (anne25)


Lesenswert?

Hallo Leute :)

Ich bin ein Neuling, wenn es um das Thema µC geht. Kann mir bitte jemand 
kurz erklären wie man bei einem µC (STM32) bei einer Taktrate von z.B. 
48MHz  für ein PWM Signal folgende Konfigurationen berechnet:

1)  Prescaler:
2)  Counter Period:
3)  Pulse:

Beispiel:
µCTakt =48Mhz
Timer = 16 Bit
Gesuchte Frequenz von 100Hz mit 50% zu 50% Tastverhältnis.

Vielen Dank im Voraus!

von pegel (Gast)


Lesenswert?


von Holger (Gast)


Lesenswert?

Such doch mal das sog. "Reference Manual" auf der Webseite von ST raus, 
da stehen die ganzen Formeln drin.

von Ingo L. (corrtexx)


Lesenswert?

PWM_Periode = 48000;
Prescaler = 10;
Comparewert = 48000/2;

von Anne J. (anne25)


Lesenswert?

Ingo L. schrieb:
> PWM_Periode = 48000;
> Prescaler = 10;
> Comparewert = 48000/2

Danke:)

Aber wie berechne ich diese?
Woher weiß ich welchen Prescaler ich benutzen soll?
Hast du hier einfach einen selber ausgewählt? Wenn ja dann wieso gerade 
diesen?

Für eine Schritt für Schritt Einleitung währe ich dir sehr dankbar. Wenn 
es auch eine Grafische Darstellung davon gäbe, dass würde mir auch sehr 
helfen das ganze richtig zu verstehen.

von Ingo L. (corrtexx)


Lesenswert?

Anne J. schrieb:
> Woher weiß ich welchen Prescaler ich benutzen soll?
> Hast du hier einfach einen selber ausgewählt? Wenn ja dann wieso gerade
> diesen?
Nachdenken. 48MHz/100Hz = 480000 Timerincremte. 480000 ist zu groß für 
16Bit. Also runterteilen:
Prescaler = 2 => 240000 Incremente => immernoch zu groß.
Prescaler = 3 => 160000 Incremente => immernoch zu groß.
Prescaler = 4 => 120000 Incremente => immernoch zu groß.
...
...
Prescaler = 8 => 60000 Incremente => Aha! Passt. Geht also ab hier.

Die 10 habe ich nur gewählt weil die mir auf Anhieb eingefallen sind, 
obwohl 8 auch nahe lag.

> Für eine Schritt für Schritt Einleitung währe ich dir sehr dankbar. Wenn
> es auch eine Grafische Darstellung davon gäbe, dass würde mir auch sehr
> helfen das ganze richtig zu verstehen.
Das kannst du dir ruhig mal selber überlegen, es wird dir keiner die 
Hausaufgaben machen. Vor allem: Wer stellt dir solche Aufgaben wenn du 
keinen Plan von Garnichts hast?!

> Ich bin ein Neuling
> µC (STM32)
Das macht natürlich immer Sinn... Fang lieber auf nem kleinen AVR an 
Laufen zu lernen bevor du dich ans Steuer eines Autos setzt...

von Christopher J. (christopher_j23)



Lesenswert?

Anne J. schrieb:
> 1)  Prescaler:
> 2)  Counter Period:
> 3)  Pulse:

Das hört sich doch sehr nach CubeMX an.

Anne J. schrieb:
> Beispiel:
> µCTakt =48Mhz
> Timer = 16 Bit
> Gesuchte Frequenz von 100Hz mit 50% zu 50% Tastverhältnis.

Mal eins nach dem anderen:

Hardware-PWM funktioniert bei den STM32 mit "general-purpose" Timern 
oder "advanced" Timern. Die "advanced" Timer können halt noch ein 
bisschen mehr, also würde ich im Reference Manual das Kapitel über 
"general-purpose" Timer aufschlagen. Außerdem kann ein Timer durchaus 
entweder als Up- oder Downcounter konfiguriert werden. Im folgenden gehe 
ich mal von einem Upcounter aus.

Für Hardware-PWM sind vier Timer-Register besonders wichtig:
1. PSC (Prescaler), entspricht deinem "Prescaler"
2. ARR (Auto Reload Register), entspricht deinem "Counter Period"
3. CCRx (Capture Compare Register Channel x), entspricht deinem "Pulse"
4. CNT (Counter), das eigentliche Timer-Register

Der Prescaler teilt den Takt der an ihm anliegt (CK_PSC) durch PSC+1 und 
reicht ihn an den Timer weiter, d.h. der Takt des Timers (CK_TIM) ist 
CK_PSC/(PSC+1) (ein Wert von 0 im PSC Register teilt offensichtlich 
nicht durch Null).

Mit diesem Takt wird nun CNT (der Counter) inkrementiert (siehe 
angehängtes Bild "counter-timing-diagram"). Wenn CNT>ARR wird CNT auf 0 
zurückgesetzt und beginnt von neuem (siehe ebenfalls 
"counter-timing-diagram"). In dem angehängten Bild ist ARR=36.

Die PWM am Ausgang wird durch einen Vergleich von CNT und CCRx erzeugt. 
Wenn CCRx=CNT wird OCXREF=0 (siehe angehängtes Bild "edge-aligned-pwm"). 
Was dann genau am Ausgang passiert hängt noch davon ab ob "PWM Mode 1" 
oder "PWM Mode 2" ausgewählt ist und wie die Polarität des Ausgangs 
gewählt ist. Das ist aber für 50% Tastverhältnis eher uninteressant. Im 
Standardfall (PWM Mode1 und Polarität "active high") ist der Ausgang 
"high" wenn OCXREF=1 ist. Entsprechende Hinweise findest du im Reference 
Manual im Abschnitt "Capture Compare Mode Register" (für PWM Mode 1/2), 
sowie "Capture Compare Enable Register" (für die Polarität).

Zusammengefasst:
Die Frequenz mit der der Timer hochzählt ist CK_PSC/(PSC+1), die Dauer 
eines "Tick" des Timers (nennen wir es mal T_t) entsprechend der 
Kehrwert (PSC+1)/CK_PSC.
Die Periodendauer ist dann (ARR+1)*T_t und deine Frequenz entsprechend 
der Kehrwert.
Die Pulsdauer ist CCRx*T_t.
Das Tastverhältnis ist Pulsdauer/Periodendauer.

Der Rest ist reine Formelumstellerei mit den Randbedingungen, dass bei 
einem 16bit Timer die Werte im Bereich von 0-65535 sein müssen. 
Allgemein gilt aber je höher der Prescaler desto niedriger ist die 
Auflösung bei der eigentlichen PWM. Mal als Beispiel:

PSC_CK = 48 MHz

PSC = 47999 (="Prescaler") -> CK_TIM = 1 kHz -> T_t = 1 ms
ARR = 9 (="Counter Period") -> Periodendauer = (9+1) * T_t = 10 ms -> 
PWM-Frequenz 100 Hz
CCRx = 5 (="Pulse") -> Pulsdauer = 5 ms -> Tastverhältnis 50%

Bei dieser Einstellung des Prescalers kann man das Tastverhältnis aber 
nur noch in Schritten von 10% einstellen. Will man einfach nur fix 50% 
ist das aber eigentlich auch egal.


Ingo L. schrieb:
>> Ich bin ein Neuling
>> µC (STM32)
> Das macht natürlich immer Sinn... Fang lieber auf nem kleinen AVR an
> Laufen zu lernen bevor du dich ans Steuer eines Autos setzt...

Es gibt durchaus Leute die können Auto fahren aber haben noch nie auf 
einem Bobby-Car gesessen. Soll ich mir jetzt also ein Bobby-Car zulegen 
wenn ich Auto fahren lernen will, nur damit ich schonmal ein Lenkrad in 
der Hand hatte? In jedem Fall gilt doch RT(F)RM.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

> Ingo L. schrieb:
>>> Ich bin ein Neuling
>>> µC (STM32)
>> Das macht natürlich immer Sinn... Fang lieber auf nem kleinen AVR an
>> Laufen zu lernen bevor du dich ans Steuer eines Autos setzt...
>
> Es gibt durchaus Leute die können Auto fahren aber haben noch nie auf
> einem Bobby-Car gesessen. Soll ich mir jetzt also ein Bobby-Car zulegen
> wenn ich Auto fahren lernen will, nur damit ich schonmal ein Lenkrad in
> der Hand hatte? In jedem Fall gilt doch RT(F)RM.

Ja, so ist es. Einfach mal in einer ruhigen Stunde mit einem Timer 
beginnen und dazu im Referenzhandbuch die Sachen durchlesen.

Sehr nützlich, da sehr kompakt: STM32SnippetsF0

Dazu gibt es im Referenzhandbuch im Anhang für jeden Hardwareblock 
(Timer, ADC etc.) kurze Code-Beispiele, die nur auf CMSIS (stm32fxxxx.h) 
aufsetzen und die entsprechende Initialisierungen zeigen. Beim F0 wäre 
das bspw.
"A.9.7 Output compare configuration code example". In Kombination mit 
"A.4.2 Alternate function selection sequence code example" erhält man 
dann die gewünschte PWM am entsprechenden Pin.

Also: Referenzhandbuch lesen - und nicht von den >1000 Seiten 
abschrecken lassen. Das ist eine Referenz: man sucht sich immer nur das 
Kapitel raus, welches man benötigt.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Anne J. schrieb:
> Für eine Schritt für Schritt Einleitung währe ich dir sehr dankbar

AN4013 bei ST.

von Anne J. (anne25)


Lesenswert?

Vielen Dank für diese ausführliche Erklärung :).

Soweit ich es jetzt verstanden habe:

fµC=48Mhz
fsoll=100Hz

1.Schritt:

Man berechnet sich einen vernünftigen Takt:

ftakt=fµC/PSC+1  -> Ttakt =PSC+1/ftakt  --> z.B.


Ttakt =47+1/48MHz
Ttakt = 1µs

was dabei zu beachten ist:

fµC/(fsoll*PSC+1) < 2^Timerwahl   // 8 Bit oder 16 Bit Timer

Ich erhalte dadurch die Taktrate für meinen Timer-Register.

2.Schritt:

In Schritt 2 wurde ich persönlich so vorgenen:
Ich habe eine fsoll =100Hz -> Tsoll= 10ms

Um die Taktanzahl zu Bestimmen, die für 10ms gebaucht wird:

1 Takt  = 1µs
x Takte = 10 ms ------>
xTakte= (1/1µs)*10ms
xTakte= 10 000


ARR Währe dann:10 000-1= 9999
und
CCRx= 5000

Lösung:
ARR=9999
PSC= 47
CCRx= 5000
ist das so korrekt, oder bin ich da ganz falsch? :/

von Christopher J. (christopher_j23)


Lesenswert?

Anne J. schrieb:
> Lösung:
> ARR=9999
> PSC= 47
> CCRx= 5000

Ja das sollte so passen und der Rechenweg (soweit ich das sehe) passt 
auch.

Anne J. schrieb:
> fµC=48Mhz

Hier muss man noch beachten, dass die Timer nicht zwingend mit der 
Frequenz des uC laufen, sondern mit dem Takt von APBx und ggf. noch mit 
einem zusätzlichen Teiler oder Multiplikator. Da du von 48MHz ausgehst 
tippe ich mal auf einen STM32F0 und da läuft im einfachsten Fall einfach 
alles mit 48MHz (uC, sowie sämtliche Timer). Hat man einen F1, F3 oder 
F4 sieht das schon wieder ganz anders aus. Einfach mal im Handbuch nach 
"clock tree" suchen.


Anne J. schrieb:
> fµC/(fsoll*PSC+1) < 2^Timerwahl   // 8 Bit oder 16 Bit Timer

Nur so als Hinweis: 8 Bit Timer gibt es beim STM32 meines Wissens keine 
mehr, sondern nur 16 und 32 Bit.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.