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 :-)
Eine Division kostet 14 Zyklen, eine Multiplikation nur einen, also wäre es schneller mit 0,5 zu multiplizieren
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
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?
Vielleicht spuckt dir der Compiler Assemblercode aus, dann müsstest du sehen ob er FPxx Opcodes aufruft
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?
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!
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.
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?
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.
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.
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...
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.
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.
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.
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.
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...
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.
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.
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
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.
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.
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!
Was willst du eigentlich mit 50 tausend Messungen pro Sekunde regeln? Welches Ding kann so schnell auf Änderungen des Stellgliedes reagieren?
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
Die Bewertungen sind Quatsch für Clowns. Nicht weiter drüber nachdenken, spart Nerven.
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
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
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.
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. --
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?
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?
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.
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 ;)
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
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.
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.
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..
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.
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.
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...
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).
eine PID Formel mit float hatte ich im F407 mal ausgemessen, brauchte 0,54 µs.
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!
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?
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...
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! :-)
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.
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.
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.
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.
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..
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.
RH schrieb: > Analog Komparatoren haben meine ich nur die STM32F3x und manche STM32Lx. Und fast jeder verschissene AVR8, manche davon haben sogar mehrere...
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?
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. ;-)
Carl D. schrieb: > Die Abkürzung, die er nicht versteht, hat sich über seine Sammlung > verteilt ;-) Was für ein ??
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.