Forum: Mikrocontroller und Digitale Elektronik Rechenzeitoptimierung STM32F4


von RH (Gast)


Lesenswert?

Hallo,

für ein Paper an der Uni suche ich momentan nach Quellen bezüglich 
rechenzeitoptimierter Programmierung des STM32. Da dieser ja eine FPU 
besitzt bin ich mir nicht sicher, ob typisch Code-Optimierungen, wie das 
Verwenden von Integer-Variablen im Gegensatz zu Float, Teilen durch 
Potenzen von 2^n wirklich einen erheblichen Vorteil bringen.
Bisher bin ich nicht im Netz fündig geworden und wollte mal in die Runde 
fragen, ob jemand eine Quelle zu dem Thema kennt. Bzw. an die STM32 
Programmierer: Habt ihr irgendwelche eigenen Code-Regeln, um euren Code 
so schlank wie möglich zu halten? Achja das nicht Verwenden der HAL sei 
mal ausgeschlossen, es geht in erster Linie um arithmetische 
Operationen.

Danke im Voraus :-)

von blub (Gast)


Angehängte Dateien:

Lesenswert?

Eine Division kostet 14 Zyklen, eine Multiplikation nur einen, also wäre 
es schneller mit 0,5 zu multiplizieren

von Dunno.. (Gast)


Lesenswert?

Was hindert dich denn, es auszuprobieren?

Wäre das zu praxisnah?

von RH (Gast)


Lesenswert?

blub schrieb:
> Eine Division kostet 14 Zyklen, eine Multiplikation nur einen, also wäre
> es schneller mit 0,5 zu multiplizieren

Danke für den PDF-Hinweis!

Dunno.. schrieb:
> Was hindert dich denn, es auszuprobieren?
>
> Wäre das zu praxisnah?

Habe ich auch schon überlegt. Ich möchte einen PID Algorithmus so 
effizient wie möglich umsetzen. Dazu gehören auch Sachen wie das 
Einlesen des ADC etc. Zum Testen habe ich jetzt mal einen 
PI-Regelalgorithmus geschrieben, der das Auswerten des ADC schon auf die 
DMA übertragen hat. Durch setzen eines GPIO vor und nach dem Algorithmus 
teste ich die Laufzeit. Der Algorithmus wird über einen Timer IRQ 
periodisch aufgerufen. Momentan benötige ich ca. 10 µs, da ich zwar die 
DMA das Auslesen des ADC überlasse aber ja trotzdem auf dessen 
Ergebnisse warten muss. Wegen starker Ungenauigkeit am ADC ist außerdem 
noch ein Software Oversampling eingefügt. Alles zusammen alles andere 
als effizient also...

Jetzt stelle ich mir die Frage, wie ich also den algorithmus optimiere.
Aktuell siehts ja in etwa so aus:

ISR Start -> ( 10x (ADCStartConversion -> PollForDMAEndOfTransfer -> 
addiere auf Summe) -> bilde Mittelwert -> Wandle ADC Wert in Regelgröße 
-> bilde e -x -> yk = yk + Kp * ( e - e_alt) + Ki * e -> e_alt = e -> 
Ende des Regelalgorithmus

von RH (Gast)


Lesenswert?

blub schrieb:
> Eine Division kostet 14 Zyklen, eine Multiplikation nur einen, also wäre
> es schneller mit 0,5 zu multiplizieren

Weißt du, ob die Verwendung FPU standardmäßig im Compiler aktiviert ist?

von blub (Gast)


Lesenswert?

Vielleicht spuckt dir der Compiler Assemblercode aus, dann müsstest du 
sehen ob er FPxx Opcodes aufruft

von Sven B. (scummos)


Lesenswert?

Also moment, du hast eine ISR und holst dir da ADC Samples, pollst 
aber in der ISR ob das DMA fertig ist? Was genau bringt dir jetzt das 
DMA?

von Mr.T (Gast)


Lesenswert?

RH schrieb:
> Weißt du, ob die Verwendung FPU standardmäßig im Compiler aktiviert ist?

Du meinst sicher DEN Compiler. Es gibt ja schließlich nur einen!

von c-hater (Gast)


Lesenswert?

RH schrieb:

> ISR Start -> ( 10x (ADCStartConversion -> PollForDMAEndOfTransfer ->
> addiere auf Summe) -> bilde Mittelwert -> Wandle ADC Wert in Regelgröße
> -> bilde e -x -> yk = yk + Kp * ( e - e_alt) + Ki * e -> e_alt = e ->

Wenn irgendwo "Poll" vorkommt, ist die Effizienz sowas von im Arsch...

Du musst lernen, wie man nebenläufig programmiert. Sprich: Starte DMA, 
sorge dafür, dass die am Ende einen Interrupt auslöst. Das war's für den 
ersten Zyklus. Ab dem zweiten läuft es anders.

Getriggert wird er (und auch alle folgenden) durch das Auftreten des 
DMA-fertig-Interupts. Er fängt dann allerdings erstmal genauso wieder an 
wie der erste: Starte DMA, sorge dafür, dass die am Ende einen Interrupt 
auslöst. Aber jetzt wird's anders als beim ersten Zyklus. Du 
verarbeitest nämlich jetzt die Daten des ersten DMA-Laufs PARALLEL zu 
dem DMA-Lauf des zweiten Zyklus.

Sprich: dein Regler läuft mit ADC-Samplerate/10. Und der Code zur 
Verarbeitung kann bis zu dieser Grenze dauern, ohne dass sich daran 
irgendwas ändert.

von RH (Gast)


Lesenswert?

Sven B. schrieb:
> Also moment, du hast eine ISR und holst dir da ADC Samples, pollst
> aber in der ISR ob das DMA fertig ist? Was genau bringt dir jetzt das
> DMA?

Das ist ja der Punkt des nicht optimierten Codes. Ich will ja einen 
"schlechten" Code mit einem "guten" vergleichen.
Allerdings weiß ich nicht genau wie ich das Samplen des ADC optimieren 
soll. Der I Anteil des PI-Reglers schreibt ja vor, dass ich zu immer 
genau festgelegten Zeitpunkten (t = k * T, t ist ein um k vielfaches der 
Abtastrate) die Spannung am ADC messe. Wenn ich den ADC wild messen 
lasse und in die DMA schreibe, habe ich ja keine definierten 
Abtastzeitpunkte. Außerdem muss ich ja wegen Rauschen am ADC den 
Mittelwert, mehrerer direkt aufeinander folgenden Messungen bestimmen, 
was ja auch nur durch die CPU berechnet werden kann. Ist es vielleicht 
sinnvoller die ADC Werte der jeweils letzten Abtastperiode zu nehmen und 
sagen wir 10 Werte von der DMA in ein Array schreiben zu lassen, woraus 
dann durch eine For-Schleife am Anfang der Regler-ISR der Mittelwert 
gebildet wird? so spart man sich immerhin die Sampling-Zeit und den 
DMA-Transfer...
Ist das verständlich erklärt?

von Martin B. (ratazong)


Lesenswert?

Die Verwendung der floating point unit im F4 setzt voraus, dass es im 
Compiler aktiviert wird. Der kann nur floats (32 bit) und keine doubles 
(64 bit). Beim F7 ist das anders.

Falls Du fp im Interrupt nutzen willst, musst Du sicherstellen, dass die 
fp Register auch auf dem Stack gesichert werden, sonst passiert 
Unvorhersehbares. Beim STM32 geht das über ein Prozessorregister. Alle 
Irq Aufrufe gehen dann langsamer. Deshalb ist das standardmäßig nicht 
der Fall.

Im allgemeinen ist die Verwendung von fp Befehlen deutlich schneller als 
die Rechnung mit Integerrechnung mit int32_t. Nur bei 16 bit Precision 
kann die Integerrechnung schneller sein.

von Stefan F. (Gast)


Lesenswert?

RH schrieb:
> Ich möchte einen PID Algorithmus so
> effizient wie möglich umsetzen.

Dann würde ich als erste mal auf Fließkomma-Artihmetik verzichten.

von RH (Gast)


Lesenswert?

c-hater schrieb:
> Getriggert wird er (und auch alle folgenden) durch das Auftreten des
> DMA-fertig-Interupts. Er fängt dann allerdings erstmal genauso wieder an
> wie der erste: Starte DMA, sorge dafür, dass die am Ende einen Interrupt
> auslöst. Aber jetzt wird's anders als beim ersten Zyklus. Du
> verarbeitest nämlich jetzt die Daten des ersten DMA-Laufs PARALLEL zu
> dem DMA-Lauf des zweiten Zyklus.

Ah, das ist natürlich ein wesentlich besserer Ansatz...

von RH (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Dann würde ich als erste mal auf Fließkomma-Artihmetik verzichten.

Das ist ja eben die Frage, ob es wirklich so ist.

Martin B. schrieb:
> Im allgemeinen ist die Verwendung von fp Befehlen deutlich schneller als
> die Rechnung mit Integerrechnung mit int32_t. Nur bei 16 bit Precision
> kann die Integerrechnung schneller sein.

Martin B. schreibt ja genau das Gegenteil.

von Stefan F. (Gast)


Lesenswert?

RH schrieb:
> Weißt du, ob die Verwendung FPU standardmäßig im Compiler aktiviert ist?

Ich glaube, der arm-gcc Compiler nutzt die FPU, wenn folgende Parameter 
gesetzt sind:

-mfpu=fpv4-sp-d16 -mfloat-abi=hard

Siehe https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html

"The default depends on the specific target configuration." Was auch 
immer das heißen soll.

von Sven B. (scummos)


Lesenswert?

RH schrieb:
> Sven B. schrieb:
>> Also moment, du hast eine ISR und holst dir da ADC Samples, pollst
>> aber in der ISR ob das DMA fertig ist? Was genau bringt dir jetzt das
>> DMA?
>
> Das ist ja der Punkt des nicht optimierten Codes.

Ok, sehe ich auch so, aber das hat halt genau überhaupt nichts mit der 
Frage aus dem Eingangsposting zu tun ;)
Dein Problem ist also nicht irgendwelche Floating-Point vs 
Integer-Performance, sondern dass die CPU busy-loopt während sie auf 
Peripherie wartet.

Ansätze zur Lösung wurden ja schon formuliert.

von RH (Gast)


Lesenswert?

Sven B. schrieb:
> Ok, sehe ich auch so, aber das hat halt genau überhaupt nichts mit der
> Frage aus dem Eingangsposting zu tun ;)
> Dein Problem ist also nicht irgendwelche Floating-Point vs
> Integer-Performance, sondern dass die CPU busy-loopt während sie auf
> Peripherie wartet.

OK, stimmt. Allerdings geht eben auch um die Frage, ob der Regler mit 
Floating-Points oder Integer-Variablen schneller ist. Ich denke 
letztendlich werde ich es Montag mal einfach am Oszi durchs Togglen 
eines GPIO testen und mal in den Compiler-Einstellungen der CubeIDE nach 
Einstellungen der FPU suchen.

von c-hater (Gast)


Lesenswert?

RH schrieb:

> OK, stimmt. Allerdings geht eben auch um die Frage, ob der Regler mit
> Floating-Points oder Integer-Variablen schneller ist.

Du hast das nicht richtig verstanden. Diese Sache spielt nur dann eine 
Rolle, wenn die Verarbeitung länger dauert als Samplefrequenz/10. (Oder 
wenn noch für andere Sachen Rechenleistung benötigt wird).

Solange die Rechnerei kürzer ist als die Periode von fs/10 und es keine 
weiteren Aufgaben zu erledigen gibt, ist es scheißegal, wie lange sie 
genau dauert. Der MCU ist es ziemlich Wurscht, ob sie hochwichtige 
Rechenaufgaben löst oder in einer leeren Endlosschleife rumidelt...

von Stefan F. (Gast)


Lesenswert?

Die Nutzung von Fließkomma-Artihmetik bringt auch die Notwendigkeit der 
Konvertierung von und zu Integer mit sich. Dazu kommt, dass Interrupts 
langsamer werden, weil zusätzlich zu den CPU Registern die FPU Register 
gesichert werden.

Ich schätze, dass man letztendlich nur durch einen Vergleich in der 
konkreten Anwendung zu einer belastbaren Aussage kommt.

Vorher müssen natürlich die Warteschleifen in Ordnung gebracht werden, 
sonst  vergleicht man faule Äpfel mit faulen Birnen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich glaube, der arm-gcc Compiler nutzt die FPU, wenn folgende Parameter
> gesetzt sind:
>
> -mfpu=fpv4-sp-d16 -mfloat-abi=hard

Jo, so sollte das aussehen. Aber dann kommen die geforderten Libraries 
(libm) und da legt z.B. TrueStudio immer noch einige Steine in den Weg. 
Kompiliert es, umso besser, aber ich kämpfe z.B. mit Meldungen wie 
'Kompiler benutzt 'vfp' Instruktionen, obwohl der MC sie nicht 
unterstützt' und rummeckern, das er die ARM includes zwar findet, aber 
nicht die Library.

von Sven B. (scummos)


Lesenswert?

RH schrieb:
> OK, stimmt. Allerdings geht eben auch um die Frage, ob der Regler mit
> Floating-Points oder Integer-Variablen schneller ist.

Das ist aber ein akademisches Philosophie-Spaßprojekt. Die 
Ingenieurs-Frage ist, wie schnell muss es denn sein und wie erreicht man 
das. Dazu muss man sich mit hoher Wahrscheinlichkeit erstmal mit dem 
genannten Punkt befassen und dann nochmal messen.

An einer Stelle drei CPU-Zyklen wegzuoptimieren während an anderer 
Stelle hunderttausende verschwendet werden ist schlicht vergeudete 
Lebenszeit.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Sven B. schrieb:
> An einer Stelle drei CPU-Zyklen wegzuoptimieren während an anderer
> Stelle hunderttausende verschwendet werden ist schlicht vergeudete
> Lebenszeit.

Ja, sehe ich auch so.

von Gerd E. (robberknight)


Lesenswert?

c-hater schrieb:
> Solange die Rechnerei kürzer ist als die Periode von fs/10 und es keine
> weiteren Aufgaben zu erledigen gibt, ist es scheißegal, wie lange sie
> genau dauert. Der MCU ist es ziemlich Wurscht, ob sie hochwichtige
> Rechenaufgaben löst oder in einer leeren Endlosschleife rumidelt...

Nicht in allen Fällen: Wenn es darauf ankommt den Energieverbrauch des 
Prozessors zu verringern (z.B. wg. Batteriebetrieb), macht es oft Sinn 
den Prozessor schnell fertigrechnen zu lassen, und dann statt einer 
Endlosschleife einen energiesparenden Schlafmodus zu aktivieren.

von RH (Gast)


Lesenswert?

Gut, zusammenfassend lässt sich also sagen, dass definitiv das 
Hauptproblem das Warten auf die Speicherung der DMA Werte ist (was mir 
ja auch bewusst war). Weil das Warten aber im Verhältnis zur 
Floating-Point oder Integer Rechnung einen wesentlich größeren Einfluss 
hat sollte dies erstmal soweit minimiert werden, dass egal wie eine 
Rechenzeit des Algorithmus von fs/10 ermöglicht wird. Angenommen ich 
Trigger die ADCConversion mit 50 KHz muss ich bei 10 vorgenommenen ADC 
Messungen diese in ungefähr 1/5000 s = 0,2 ms "abgearbeitet" haben.

c-hater schrieb:
> Solange die Rechnerei kürzer ist als die Periode von fs/10 und es keine
> weiteren Aufgaben zu erledigen gibt, ist es scheißegal, wie lange sie
> genau dauert. Der MCU ist es ziemlich Wurscht, ob sie hochwichtige
> Rechenaufgaben löst oder in einer leeren Endlosschleife rumidelt...

Ja gut das stimmt, gerne würde ich neben dem Regel-Algorithmus dann 
allerdings soviel Rechenleistung zur Verfügung haben wie es geht, daher 
ja der Optimierungsgedanke.

Danke auf jeden Fall schon einmal bis jetzt für die Tipps!

von Stefan F. (Gast)


Lesenswert?

Was willst du eigentlich mit 50 tausend Messungen pro Sekunde regeln?

Welches Ding kann so schnell auf Änderungen des Stellgliedes reagieren?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> Solange die Rechnerei kürzer ist als die Periode von fs/10 und es keine
> weiteren Aufgaben zu erledigen gibt, ist es scheißegal, wie lange sie
> genau dauert. Der MCU ist es ziemlich Wurscht, ob sie hochwichtige
> Rechenaufgaben löst oder in einer leeren Endlosschleife rumidelt...

 Genau.
 Aber mal etwas anderes:
 Habe erst jetzt bemerkt, dass es zu jedem Beitrag Bewertungen gibt
 und möchte gerne wissen welcher schwachsinniger Idiot jeden aber auch
 jeden Beitrag von c-hater negativ bewertet...
 Selbst konstruktive Beiträge von ihm werden negativ bewertet.

 Wie winzig muß der IQ von diesem gehirnlosem Insekt sein, um so etwas
 dauernd zu machen?
 Glaubt der Retard wirklich, seine idiotischen Minuse bedeuten irgend
 jemandem etwas?

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Die Bewertungen sind Quatsch für Clowns. Nicht weiter drüber nachdenken, 
spart Nerven.

von Markus F. (mfro)


Lesenswert?

ha, und gleich Punktabzug für die Bemerkung bekommen ;)

von Miss Ratgeber (Gast)


Lesenswert?

Das holen eines ADC-Wertes per DMA bringt genau Null Gummipunkte.
Floats in ISRs sind auf ARMen eine schlechte Idee.

Richtiger Ansatz:

Per Timer die CPU wecken.

Dann in der Main:
Den ADC-Wert aus dem vorhergehenden Zyklus mit dem Algorithmus
verwursten. Da kann dann auch gerne mit FLoats gerechnet werden.
Stellwert ausgeben.
ADC Wandlung anstossen.
Schlafen legen.

Goto Oben

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Martin B. schrieb:
> Beim F7 ist das anders.
Eine D-FPU gibts erst ab F76x und F77x.

Martin B. schrieb:
> Falls Du fp im Interrupt nutzen willst, musst Du sicherstellen, dass die
> fp Register auch auf dem Stack gesichert werden, sonst passiert
> Unvorhersehbares. Beim STM32 geht das über ein Prozessorregister. Alle
> Irq Aufrufe gehen dann langsamer. Deshalb ist das standardmäßig nicht
> der Fall.

Dafür gibts in dem Register noch ein Bit.
Irgendwas mit Lazy Stacking.
Für die FP Register wird Platz auf dem STack reserviert, aber kopiert 
wird erst wenn der IRQ die FPU nutzen will.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/DAFGGBJD.html

von c-hater (Gast)


Lesenswert?

Miss Ratgeber schrieb:

> Das holen eines ADC-Wertes per DMA bringt genau Null Gummipunkte.

Er holt ja zehn und nicht nur einen.

> Floats in ISRs sind auf ARMen eine schlechte Idee.

Er muss ja nicht notwendigerweise in der ISR rechnen. Er kann wunderbar 
auch die Parallelverarbeitung in main abhandeln. Das Entscheidende ist 
die Parallelität.

> Per Timer die CPU wecken.

Wozu soll der Timer gut sein? Er hat doch eine ADC am Laufen, die mit 
konstanter Samplerate arbeitet. Das ist genauso gut wie ein Timer. 
Eigentlich sogar noch besser, denn es macht weder Sinn, schneller zu 
regeln, als die Messwerte reinkommen, noch langsamer. Sprich: die Quelle 
der Messwerte ist die bestgeeignete Instanz, um den Verarbeitungszyklus 
zu kontrollieren.

von The A. (the_a343)


Lesenswert?

Martin B. schrieb:
> Im allgemeinen ist die Verwendung von fp Befehlen deutlich schneller als
> die Rechnung mit Integerrechnung mit int32_t. Nur bei 16 bit Precision
> kann die Integerrechnung schneller sein.

Da wäre ich jetzt mal vorsichtig:
- bei Verwendung der Gleitkommaeinheit gibt es noch Overhäd durch das 
Load/Store der Werte in die FPU hinein/heraus
- der int32 MUL arbeitet auch in einem Takt, das Ergebnis liegt dann 
schon in den CPU Registern
  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/CHDDIGAC.html
- bei int16, int8 operationen muss man noch ein Overhead durch die 
Vorzeichen Normalisierung beachten;
  daher lieber mit int32 rechnen

Da float Werte nur eine Mantisse von 24bit haben, sollte man sich schon 
überlegen, ob da nicht informationen verloren gehen ...

Im Fall der angesprochenen Analogwandlung ist das aber wohl alle egal.
Ich würde dem Compiler so früh wie möglich die floats vorwerfen.
Der optimiert dann schon. Das ist sein Job.

Grüße, Adib.
--

von Stefan F. (Gast)


Lesenswert?

The A. schrieb:
> Ich würde dem Compiler so früh wie möglich die floats vorwerfen.
> Der optimiert dann schon. Das ist sein Job.

Das ist ein Punkt, der mich interessiert. Ich vertraue darauf, dass der 
Compiler fast immer besser optimiert, als ich es manuell könnte. Zum 
Beispiel ist es ja vollkommen selbstverständlich, dass eine Integer 
Division durch 2,4,8,16,... in eine viel schnellere shift Operation 
optimiert wird - sofern der Divisor konstant ist.

Wie ist das bei Fließkomma-Arithmetik? Optimiert der Compiler da auch so 
vollständig, wie man das von Integer gewohnt ist, oder sind da 
signifikante Einschränkungen bekannt?

von RH (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Was willst du eigentlich mit 50 tausend Messungen pro Sekunde regeln?
>
> Welches Ding kann so schnell auf Änderungen des Stellgliedes reagieren?

Im konkreten Fall handelt es sich um eine digitale Regelung eines 
Buck-Converters. Die hohe Zahl der Messung ist nur nötig, da dass 
Messsignal stark schwankt, bzw. der die Werte im ADC Register echt 
relativ stark schwanken (+/- 100 Schritte bei 12Bit-Auflösung). Da ich 
auf die schnelle keinen passenden RC-Filter hatte hab ichs halt mit 
Oversampling und MIttelwert-Bilden versucht.

Der eigentliche Regler regelt ja jetzt oben im Beispiel nur alle 10 
Abtastperioden -> sprich bei 50 KHz Abtastrate mit 5 KHz was für eine 
Spannungsregelung doch okay sein sollte oder?

von Stefan F. (Gast)


Lesenswert?

RH schrieb:
> Im konkreten Fall handelt es sich um eine digitale
> Regelung eines Buck-Converters.

Nur so als keiner Hinweis: An der Idee sind hier schon viele 
gescheitert. Die Regelung überlässt man speziellen IC's die dafür 
gemacht sind. Mikrocontroller sind dafür im Allgemeinen die falsche 
Wahl.

Was du aber gerne machen kannst: Mit einem Mikrocontroller die 
Referenzspannung (Sollwert) erzeugen, und dann mit einem herkömmlichen 
Schaltregler die Ausgangsspannung daran angleichen.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Stefan ⛄ F. schrieb:
> Nur so als keiner Hinweis: An der Idee sind hier schon viele
> gescheitert. Die Regelung überlässt man speziellen IC's die dafür
> gemacht sind. Mikrocontroller sind dafür im Allgemeinen die falsche
> Wahl.

Sag das meiner Lüftersteuerung in meiner E-Last ;)

von Markus F. (mfro)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das ist ein Punkt, der mich interessiert. Ich vertraue darauf, dass der
> Compiler fast immer besser optimiert, als ich es manuell könnte. Zum
> Beispiel ist es ja vollkommen selbstverständlich, dass eine Integer
> Division durch 2,4,8,16,... in eine viel schnellere shift Operation
> optimiert wird - sofern der Divisor konstant ist.

vollkommen selbstverständlich - Hausaufgaben nicht richtig gemacht.

Wenn Du das Cortex M3 Manual schon mal studiert hättest, wüsstest Du, 
dass ein MUL genausoviele Prozessor-Zyklen braucht wie ein LSL (nämlich 
einen).

Es ist also völlig wurscht, ob multiply oder shift.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Markus F. schrieb:
> Wenn Du das Cortex M3 Manual schon mal studiert hättest, wüsstest Du,
> dass ein MUL genausoviele Prozessor-Zyklen braucht wie ein LSL (nämlich
> einen).

Danke für die Erklärung.

Ich habe das Cortex M3 Manual bisher nur überflogen, sollte ich mal 
richtig lesen.

Ich kenne mich mit älteren Controllern besser aus, wo Multiplikationen 
und Divisionen in Software-Routinen implementiert werden müssen.

von Markus F. (mfro)


Lesenswert?

Bezüglich der Division hast Du recht, die braucht 2 Zyklen.

Bei den Dingern ist es aber jedenfalls besser, das Optimieren dem 
Compiler zu überlassen und sich - wenn's auf Geschwindigkeit ankommt - 
auf schnelle Algorithmen zu konzentrieren.

von RH (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Nur so als keiner Hinweis: An der Idee sind hier schon viele
> gescheitert. Die Regelung überlässt man speziellen IC's die dafür
> gemacht sind. Mikrocontroller sind dafür im Allgemeinen die falsche
> Wahl.

Klar gibt es ICs die es wahrscheinlich besser können aber grundsätzlich 
funktioniert die Regelung auf dem µC gut! Im Anhang ist die 
Sprungantwort beim Einschalten des Wandlers zu sehen. Generell lässt 
sich die Spannung Regeln. Eine Regelung des Stroms ist sogar auch bis zu 
einem gewissen Grad möglich.

Markus F. schrieb:
> Wenn Du das Cortex M3 Manual schon mal studiert hättest, wüsstest Du,
> dass ein MUL genausoviele Prozessor-Zyklen braucht wie ein LSL (nämlich
> einen).

Also verstehe ich das so richtig, dass bei modernen ARM CPUs im Prinzip 
relativ wurscht ist, ob Integers Addiere oder Subtrahiere? Ich sollte 
drauf achten nicht zu dividieren und Floats lassen sich genauso schnell 
berechnen allerdings ist standardmäßig die FPU nicht in ISR verwendbar. 
Ein Aktivieren der FPU in Interrupts, würde diese allgemein etwas 
langsamer machen, da die FPU Register jeweils mit gesichert werden 
müssen..

von Johannes S. (Gast)


Lesenswert?

es gibt auch µC die das in HW erledigen, so ein winziger LPC810 wurde 
mal in einem make Projekt für eine Taschenlampe benutzt. Der LPC810 hat 
nicht mal einen kompletten AD Wandler, nur einen Komparator, aber der 
reicht schon in Verbindung mit dem State Controlable Timer SCT für so 
eine Aufgabe. Auch wenn das Programm Blödsinn macht läuft die Regelung 
weiter.
Ist natürlich nur das Wort zum Sonntag wenn man einen anderen µC hat :)
FP in Hardware haben so gut wie alle Cortex-M4, werden zwar auch gerne 
M4F genannt aber ich kenne keinen M4 ohne HW FP.
In einer Schrittmotoransteuerung mit F407 @168 MHz habe ich mit einem 
OnePulse Timer einen Interrupt ausgelöst und in der ISR Portpin für 
Schrittmotor Takt auf 1 und 0 gesetzt und dazwischen die Zeit für den 
nächsten Puls berechnet. Mit linearer Interpolation in FP. Das war 
trotzdem so schnell das ich für die 1,x µs min. Pulsdauer noch eine 
Verzögerungsschleife einbauen musste.

von RH (Gast)


Lesenswert?

Johannes S. schrieb:
> In einer Schrittmotoransteuerung mit F407 @168 MHz habe ich mit einem
> OnePulse Timer einen Interrupt ausgelöst und in der ISR Portpin für
> Schrittmotor Takt auf 1 und 0 gesetzt und dazwischen die Zeit für den
> nächsten Puls berechnet. Mit linearer Interpolation in FP. Das war
> trotzdem so schnell das ich für die 1,x µs min. Pulsdauer noch eine
> Verzögerungsschleife einbauen musste.

Ui, aber wofür benötigst du die Schleife? Würde der µC nicht einfach in 
die Main-Schleife zurückspringen?

Johannes S. schrieb:
> es gibt auch µC die das in HW erledigen, so ein winziger LPC810 wurde
> mal in einem make Projekt für eine Taschenlampe benutzt. Der LPC810 hat
> nicht mal einen kompletten AD Wandler, nur einen Komparator, aber der
> reicht schon in Verbindung mit dem State Controlable Timer SCT für so
> eine Aufgabe. Auch wenn das Programm Blödsinn macht läuft die Regelung
> weiter.

Alternativen gibts immer! :-)
In dem Projekt soll neben der Regelung noch im Main-Loop eventuell Daten 
gesendet und empfangen werden, daher auch der "fette" µC für die 
einfache Regelaufgabe. Damit der µC nicht die ganze Zeit mit den ISR der 
Regelung und ADC-Auswertung beschäftigt ist, soll die CPU da eben so 
wenig wie möglich zu Tun bekommen.

von Johannes S. (Gast)


Lesenswert?

RH schrieb:
> i, aber wofür benötigst du die Schleife? Würde der µC nicht einfach in
> die Main-Schleife zurückspringen?

Der Takteingang möchte auf 1 und nach 1,x µs wieder auf 0 gesetzt 
werden, das hatte ich eben einfach in der ISR gemacht.
Das geht natürlich schöner auch in HW mit dem Compare, dann müssen aber 
auch die passen GPIO frei sein.
Ging ja auch nur darum das der µC 'zu schnell' ist, selbst mit früher 
bösen FP Berechnungen in der ISR.
Das die FP Register dann zusätzlich gesichert werden müssen ist dann 
evtl. zu berücksichtigen, aber wie gesagt, der F4 ist so 
rattenschnell...

von c-hater (Gast)


Lesenswert?

RH schrieb:

> Damit der µC nicht die ganze Zeit mit den ISR der
> Regelung und ADC-Auswertung beschäftigt ist, soll die CPU da eben so
> wenig wie möglich zu Tun bekommen.

Mein Gott, so ein PID-Regler besteht im Kern aus lächerlichen drei 
Multiplikationen und zwei Additionen. Das sollte ein Teil wie der STM32 
doch wohl locker in einem Zeitfenster von 200µs leisten können und zwar 
so, dass von dem Zeitfenster immer noch fast die gesamten 200µs über 
bleiben...

Das wäre ja selbst mit einem AVR8@16MHz noch absolut kein Problem. OK, 
der würde natürlich schon einen merklichen Teil des Zeitfensters 
benötigen, aber auf jeden Fall nicht annähernd so viel, dass es kritisch 
werden würde.

Falls doch, dann ist das ein deutliches Zeichen, dass der Algorithmus 
suboptimal umgesetzt ist. Merkt man übrigens auch daran, dass halt mehr 
als drei Multiplikationen und zwei Additionen darin vorkommen (Die 
"Unwind"-Mimik für den I-Zweig sei mal außen vor).

von Johannes S. (Gast)


Lesenswert?

eine PID Formel mit float hatte ich im F407 mal ausgemessen, brauchte 
0,54 µs.

von RH (Gast)


Angehängte Dateien:

Lesenswert?

c-hater schrieb:
> Falls doch, dann ist das ein deutliches Zeichen, dass der Algorithmus
> suboptimal umgesetzt ist. Merkt man übrigens auch daran, dass halt mehr
> als drei Multiplikationen und zwei Additionen darin vorkommen (Die
> "Unwind"-Mimik für den I-Zweig sei mal außen vor).

Ja, das Hauptproblem beim Anfangsbeispiel lag ja auch definitiv beim 
Polling der ADC-DMA-Übertragung. Der PI sieht ja nur wie im Anhang zu 
sehen ist aus.

Im Regelalgorithmus befinden sich allerdings noch weitere Überprüfungen 
dazu, ob  zwischen Strombegrenzung oder Spannungsbegrenzung gewechselt 
werden muss etc. etc.. das möchte ich alles so effizient wie möglich 
machen. Dazu kommt halt das Software Oversampling der ADCs. Bin bei 
weitem kein Experte oder erfahrener STM32-Programmierer deswegen, war 
halt die Frage, wie man manche Sachen am besten umsetzt. Bisher wurde 
mir ja auch super geholfen!

von Gerd E. (robberknight)


Lesenswert?

RH schrieb:
> Im konkreten Fall handelt es sich um eine digitale Regelung eines
> Buck-Converters.
[...]
> Der eigentliche Regler regelt ja jetzt oben im Beispiel nur alle 10
> Abtastperioden -> sprich bei 50 KHz Abtastrate mit 5 KHz was für eine
> Spannungsregelung doch okay sein sollte oder?

Wie sieht es im Kurzschlussfall aus? Wenn Du den Strommesswert nur mit 5 
kHz auswertest, erscheint mir das etwas zu langsam um den FET überleben 
zu lassen. Oder hast Du dafür noch einen schnellen Komparator im 
Einsatz?

Wie sieht es mit starken Lastschwankungen aus? Also wenn Du das Ding auf 
Volllast betreibst und dann die Last schlagartig entfernst (z.B. 
Kabelbruch) , um wieviel schießt die Spannung über den Sollwert? 
Überlebt das der Rest Deiner Schaltung oder, falls die Last aus mehreren 
Modulen besteht, diese anderen Module?

von c-hater (Gast)


Lesenswert?

Gerd E. schrieb:

> RH schrieb:
>> Im konkreten Fall handelt es sich um eine digitale Regelung eines
>> Buck-Converters.
> [...]
>> Der eigentliche Regler regelt ja jetzt oben im Beispiel nur alle 10
>> Abtastperioden -> sprich bei 50 KHz Abtastrate mit 5 KHz was für eine
>> Spannungsregelung doch okay sein sollte oder?
>
> Wie sieht es im Kurzschlussfall aus? Wenn Du den Strommesswert nur mit 5
> kHz auswertest, erscheint mir das etwas zu langsam um den FET überleben
> zu lassen. Oder hast Du dafür noch einen schnellen Komparator im
> Einsatz?
>
> Wie sieht es mit starken Lastschwankungen aus? Also wenn Du das Ding auf
> Volllast betreibst und dann die Last schlagartig entfernst (z.B.
> Kabelbruch) , um wieviel schießt die Spannung über den Sollwert?
> Überlebt das der Rest Deiner Schaltung oder, falls die Last aus mehreren
> Modulen besteht, diese anderen Module?

@RH:

Das, was Gerd da schreibt, hat Hand und Fuss. Darauf solltest du dich 
konzentrieren, statt auf endlose Erwägungen, ob der eigentliche Regler 
nun in 0,5µs oder in 0,2µ fertig ist, wenn er 200µs Zeit hat für seinen 
Job...

von RH (Gast)


Lesenswert?

Gerd E. schrieb:
> Wie sieht es im Kurzschlussfall aus? Wenn Du den Strommesswert nur mit 5
> kHz auswertest, erscheint mir das etwas zu langsam um den FET überleben
> zu lassen. Oder hast Du dafür noch einen schnellen Komparator im
> Einsatz?

Im Kurzschlussfall löst ein Analog Watchdog IRQ aus. Die ADC Werte des 
Stroms werden ja mit 50 KHz gesampled. Allerdings hatte ich das bisher 
nur experimentell ausprobiert und mir dabei einen MOSFET zerschossen, 
obwohl ja eigentlich blitzschnell der IR auslösen sollte...

Gerd E. schrieb:
> Wie sieht es mit starken Lastschwankungen aus? Also wenn Du das Ding auf
> Volllast betreibst und dann die Last schlagartig entfernst (z.B.
> Kabelbruch) , um wieviel schießt die Spannung über den Sollwert?
> Überlebt das der Rest Deiner Schaltung oder, falls die Last aus mehreren
> Modulen besteht, diese anderen Module?

Da es sich um einen Abwärtswandler mit 50V Eingangsspannung handelt sind 
alle Leistungskomponenten für ca. 80 - 100V ausgelegt. Wie es am Ausgang 
aussieht wenn unter Volllast die Last entfernt wird habe ich noch nicht 
geschaut aber mehr als 50V können ja nicht rauskommen. Fraglich ist wie 
hoch die Spannung ansteigt bei z.B. 12V am Ausgang. Ich meine aber das 
sah alles im Grünen Bereich aus. Ich wollte dazu aber morgen eh 
Messungen machen! :-)

von Stefan F. (Gast)


Lesenswert?

RH schrieb:
> Allerdings hatte ich das bisher
> nur experimentell ausprobiert und mir dabei einen MOSFET zerschossen,
> obwohl ja eigentlich blitzschnell der IR auslösen sollte...

Hattest du da in einer anderen gleich oder höher priorisierten ISR eine 
Warteschleife?

Vielleicht testest du besser mit einem erhöhten Strom, den der MOSFET 
wenigstens für ein paar Sekunden aushält. An seine Leistungsgrenzen kann 
man dann später gehen, wenn die Software fertig ist.

RH schrieb:
> Fraglich ist wie
> hoch die Spannung ansteigt bei z.B. 12V am Ausgang.

(Taschen-)Lampen mit PWM Dimmern sind ein schöner Härtetest, der dennoch 
nicht allzu weit her geholt ist.

von RH (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Hattest du da in einer anderen gleich oder höher priorisierten ISR eine
> Warteschleife?
>
> Vielleicht testest du besser mit einem erhöhten Strom, den der MOSFET
> wenigstens für ein paar Sekunden aushält. An seine Leistungsgrenzen kann
> man dann später gehen, wenn die Software fertig ist.

Dass es doof war direkt an die Grenzen zu gehen, ist mir im Nachhinein 
auch aufgefallen. Das Notausschalten funktionierte auch erstmal aber 
einmal dann eben nicht.

Ich habe mich noch nicht mit den IR Prioritäten des STM32 
außeinandergesetzt. Ich kann mir vorstellen, dass beim Fehlerfall der 
Watchdog IR den Ausgang auf Null gesetzt hat und der Regler im Anschluss 
direkt wieder ein. Der Watchdog IR setzte nur den Pulse auf 0. Besser 
wäre es wohl eventuell direkt auch den Timer danach zu stoppen.

von RH (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> (Taschen-)Lampen mit PWM Dimmern sind ein schöner Härtetest, der dennoch
> nicht allzu weit her geholt ist.

da Glätte ich die zerstückelte Spannung um sie mir direkt wieder 
zerstückeln zu lassen :D Aber klar zum Testen der Reglereigenschaften 
bestimmt ziemlich gut. An und für sich sollte der Ausgangselko ja auch 
starke Lastschwankungen etwas abschwächen. Werde ich bei Gelegenheit mal 
testen. Ich glaube die Elektronische Last die ich zum Testen habe, kann 
auch Schwankende Lasten simulieren..

Hab nachgeschaut sinus-, trapez- und rechteckförmige Verläufe sind 
einstellbar.

von Gerd E. (robberknight)


Lesenswert?

RH schrieb:
> Im Kurzschlussfall löst ein Analog Watchdog IRQ aus. Die ADC Werte des
> Stroms werden ja mit 50 KHz gesampled. Allerdings hatte ich das bisher
> nur experimentell ausprobiert und mir dabei einen MOSFET zerschossen,
> obwohl ja eigentlich blitzschnell der IR auslösen sollte...

das deckt sich voll mit meiner Erfahrung, das ist so zu langsam.

Ich würde das nicht mal mit einem ADC machen, sondern einen extra 
Komparator für verwenden. Bei den STM32, die einen integrierten 
Komparator haben, kann man den extra so konfigureren, dass er einen von 
den PWM-Kanälen hardwaremäßig ausschaltet. Das ist für genau diesen Fall 
gedacht und ich empfehle das auch so zu machen.

Wenn nicht mit dem internen Komparator, dann mit einem externen und 
einem Logikgatter zwischen PWM-Ausgang des Controllers und dem Gate des 
FET.

> Da es sich um einen Abwärtswandler mit 50V Eingangsspannung handelt sind
> alle Leistungskomponenten für ca. 80 - 100V ausgelegt.

Damit meinst Du doch alles vor dem Abwärtswandler und den Abwärtswandler 
selbst, nicht aber die Teile am Ausgang des Abwärtswandlers, oder?

> Wie es am Ausgang
> aussieht wenn unter Volllast die Last entfernt wird habe ich noch nicht
> geschaut aber mehr als 50V können ja nicht rauskommen. Fraglich ist wie
> hoch die Spannung ansteigt bei z.B. 12V am Ausgang.

Genau. Stell mal 12V ein und ziehe den maximal möglichen Strom den Dein 
Buck hergibt mit einer Dummy-Load. Dann die Last schlagartig 
ausschalten/trennen und dabei die Spannung am Ausgang des Buck auf dem 
Oszi beobachten.

Mehr als 50V werden es nicht werden, aber bei 5 kHz Regelschleife 
vermute ich daß es deutlich mehr als 12 sein werden.

Wenn Du am Ausgang jetzt z.B. 2 Geräte parallel angeschlossen hast, das 
eine zieht viel Strom, das andere nur wenig, und jetzt trennst Du den 
Stromfresser, dann kann es das andere Modul grillen weil es mehr als die 
gewünschten 12 V bekommt.

> Ich wollte dazu aber morgen eh
> Messungen machen! :-)

Das empfehle ich.

von RH (Gast)


Lesenswert?

Gerd E. schrieb:
> Ich würde das nicht mal mit einem ADC machen, sondern einen extra
> Komparator für verwenden. Bei den STM32, die einen integrierten
> Komparator haben, kann man den extra so konfigureren, dass er einen von
> den PWM-Kanälen hardwaremäßig ausschaltet. Das ist für genau diesen Fall
> gedacht und ich empfehle das auch so zu machen.

Hm... ich muss mal nachschauen ich glaube mein verwendetes NUCLEO-F429ZI 
Board hat solche Komparatoren nicht... Ich bin davon ausgegangen per 
Watchdog und IR würde es reichen. Ist ja dann auch die Frage wie schnell 
der Stromsensor ist. Verbaut ist ein ACS723.

Gerd E. schrieb:
> Damit meinst Du doch alles vor dem Abwärtswandler und den Abwärtswandler
> selbst, nicht aber die Teile am Ausgang des Abwärtswandlers, oder?

Ja genau, die Lasten am Ausgang werden ganz unterschiedlich sein.

Gerd E. schrieb:
> Das empfehle ich.

Werde ich tun und hier reinposten..

von RH (Gast)


Lesenswert?

Gerd E. schrieb:
> Ich würde das nicht mal mit einem ADC machen, sondern einen extra
> Komparator für verwenden. Bei den STM32, die einen integrierten
> Komparator haben, kann man den extra so konfigureren, dass er einen von
> den PWM-Kanälen hardwaremäßig ausschaltet. Das ist für genau diesen Fall
> gedacht und ich empfehle das auch so zu machen.
>
> Wenn nicht mit dem internen Komparator, dann mit einem externen und
> einem Logikgatter zwischen PWM-Ausgang des Controllers und dem Gate des
> FET.

Ich könnte ja den Strom auch im Continous Conversion Mode auf einem 
weiteren ADC mit maximaler Samplerate rattern lassen und dort mit einem 
Analog Watchdog überwachen... dann sollte ich ja wirklich schnelle 
Reaktionszeiten. Eine andere Lösung fällt mir für den STM32F4 nicht ein. 
Analog Komparatoren haben meine ich nur die STM32F3x und manche STM32Lx.

von c-hater (Gast)


Lesenswert?

RH schrieb:

> Analog Komparatoren haben meine ich nur die STM32F3x und manche STM32Lx.

Und fast jeder verschissene AVR8, manche davon haben sogar mehrere...

von Stefan F. (Gast)


Lesenswert?

c-hater schrieb:
> Und fast jeder verschissene AVR8, manche davon haben sogar mehrere...

Meine sind nicht verschissen, sondern schön sauber. Was stellst du mit 
den teilen an, und was hat das mit diesem Thread zu tun? Bist du heute 
Abend wieder auf Mission?

von Carl D. (jcw2)


Lesenswert?

Stefan ⛄ F. schrieb:
> c-hater schrieb:
>> Und fast jeder verschissene AVR8, manche davon haben sogar mehrere...
>
> Meine sind nicht verschissen, sondern schön sauber. Was stellst du mit
> den teilen an, und was hat das mit diesem Thread zu tun? Bist du heute
> Abend wieder auf Mission?

Die Abkürzung, die er nicht versteht, hat sich über seine Sammlung 
verteilt.
;-)

von Stefan F. (Gast)


Lesenswert?

Carl D. schrieb:
> Die Abkürzung, die er nicht versteht, hat sich über seine Sammlung
> verteilt ;-)

Was für ein ??

von Gerd E. (robberknight)


Lesenswert?

RH schrieb:
> Ich könnte ja den Strom auch im Continous Conversion Mode auf einem
> weiteren ADC mit maximaler Samplerate rattern lassen und dort mit einem
> Analog Watchdog überwachen...

Musst Du ausprobieren ob das in allen Fällen schnell genug ist. Ich 
vermute wenn Du mit Deiner PWM einen Duty-Cycle nahe dem Maximum fährst, 
ist das Risiko für ein Sterben des FETs am Größten. Diesen Fall würde 
ich genauer austesten. Geh aber schon mal einen Eimer FETs kaufen...

> Eine andere Lösung fällt mir für den STM32F4 nicht ein.
> Analog Komparatoren haben meine ich nur die STM32F3x und manche STM32Lx.

Dein F429 hat ein der Tat keine integrierten Komparatoren.

Verwendest Du einen der Advanced-control timers TIM1 oder TIM8 für Deine 
PWM? Die haben einen TIMx_BKIN. Da kannst Du einen externen Komparator 
anschließen und die PWM dann bei Erreichen des Maximalstroms auf 
Hardwareebene abschalten lassen.

Dein ACS723 Stromsensor scheint nur 80kHz Bandbreite zu haben. Das 
könnte in der Tat eng werden.

Was Du eigentlich bei so einem Projekt willst, ist Cycle-by-Cycle 
Current Limiting. Also Du gibst einen maximalen Stromwert vor (z.B. per 
DAC), und der Regler kann direkt innerhalb des PWM-Taktes abschalten 
wenn dieser Stromwert erreicht wurde. Das hilft nicht nur für den Fall 
des Kurzschlusses, sondern erlaubt auch auf Stromregelung (statt 
Spannungsregelung) umzustellen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

RH schrieb:
> Hm... ich muss mal nachschauen ich glaube mein verwendetes NUCLEO-F429ZI
> Board hat solche Komparatoren nicht...

Lies mal das Kapitel über den ADC Watchdog im F4 Reference Manual. 
Könnte sein, das du genau das suchst.

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.