Hallo liebe Community, ich bin momentan in meiner Praxisphase im Dualen Studium und habe in der Elektronik Entwicklung das STM32f100RB Discovery Board als "Tutorial" für den in unseren Generator-CPU's verwendeten STM32f407. Durchgemacht habe ich bereits das Tutorial von "Diller Technologies". Selbst habe ich schon uC programmiert, allerdings auf Arduino Boards, wo es nicht so in die Tiefe geht. In dem Tutorial habe ich in Sachen Timer leider nur die Konifugration eines Outputs kennengelernt und suche momentan vergeblich im Netz nach einer Konfiguration für einen Timer Input... Mein Projekt ist es momentan Messungen mit dem STM32f100RB auszuwerten, dabei ist auch eine Messung, um eine Phasenverschiebung zwischen Strom und Spannung zu messen. Das Phasensignal wird über eine analoge Messschaltung so aufbereitet, dass am uC nur ein Takt ankommt mit bekannter Frequenz, und dessen Puls-Pausen-Verhältnis oder wenn man so will sein Mittelwert ist quasi proportional zur Phase. Nun möchte ich einen Timer bei positiver Flanke mit einer hohen Frequenz ...zwischen 10 und 20 MHz... anfangen lassen zu Zählen und bei einer fallenden Flanke soll er stoppen, die Anzahl der Messwerte ist dann proportional zu meiner Phase und ich kann diesen Wert softwaretechnisch umrechnen. Ein Ansatz wäre das Taktsignal auf zwei Ports einzulesen, bei einem Port mit steigender Flanke einen Timer starten und auf dem anderen Port einen Interrupt starten bei fallender Flanke und mit diesem den Timer zu stoppen. Kann mir hier jemand weiterhelfen?
:
Bearbeitet durch User
Ich sehe 2 AppNotes für Timer auf der Herstellerseite. Da ist "Capture" garantiert mit dabei.
Warum nimmst du keinen Tiefpass und erzeugst dir so den gleitenden Mittelwert, den kannst du mit einem ADC wunderbar auswerten. Ansonsten würde ich wohl im Reference-Manual bzw den Application-Notes danach suchen.
Danke für die schnellen Antworten. Ich versuche es nun einfach mal und messe was bei den verschiedenen Einstellungen raus kommt. In den Appli.-Notes steht nicht wirklich viel Hilfreiches. Das mit dem Tiefpass wird nicht einfach, der Takt kommt mit f = 20kHz und die Messung muss sehr exakt sein....finde da keine passende RC Kombination, die mir da passt, da dieser Mittelwert in Nähe der Resonanzfrequenz des zu messenden Schwinggebilde sich sehr schnell ändert (Phasensprung) und das sollte dann wirklich exakt gemessen werden, damit die Resonanzfrequenz auf mHz genau gemessen werden kann..
Tobias G. schrieb: > Das mit dem Tiefpass wird nicht einfach, der Takt kommt mit f = 20kHz u Tobias G. schrieb: > dann wirklich exakt gemessen werden, damit die Resonanzfrequenz auf mHz > genau gemessen werden kann.. Äh ja. Genau. Das ist eine GENAUIGKEIT von 0.000005% oder auch 0,05ppm! 1mHz von 20kHz. DA bin ich ja mal auf die Lösungen gespannt...
Also wenn ich 20kHz durch 10MHz teile kommen bei mir 0,002 raus...ich denke 500 Messwerte pro Periode dürfte doch locker realisierbar sein, oder etwa nicht? Die Timer laufen ja mit MHz-Takten also muss es ja möglich sein einen Puls von 20kHz mit 10MHz abzutasten. Die Genauigkeit liegt ja nicht in der Anzahl der Messwerte, denn die ist ja fest definiert, sondern darin, dass ich erkennen muss WANN die Anzahl der Messwerte (Zählerstand) geteilt durch die definierte Pulsbreite, den gewünschten Mittelwert bildet. Und das ist ja einfach das Auslesen des Zählerstands zu diesem Zeitpunkt. Und da kommen dann noch Laufzeiten im Prozessor zum tragen... Verstehe deshalb nicht ganz wie du auf 0,05ppm kommst...^^ 20kHz/10MHz = 0,002 = 0,2%
Entschuldige, ich hatte dich falsch verstanden, ich hatte es so verstanden, dass du die 20 kHz mit 1mHz Auflösung messen wolltest. Das war die Fressnarkose. Nur, dass ich das richtig verstehe - Du hast ein Signal, das eine Frequenz von 20 kHz hat. Und dieses Signal hat ein der Phasenlage entsprechendes Puls-Pause-Verhältnis?! Wie schnell (quantifiziert) kann sich denn die Phasenlage ändern?
Die Phasenlage ändert sich doch - bei konstanten Rahmenbedingungen - nur in Abhängigkeit von der Frequenz. Wenn also die Frequenz gewobbelt wird muss sie nur ausreichend langsam gewobbelt werden, damit die Verzögerung durch den Tiefpass ausreichend gering ist. Oder bleibt die Frequenz konstant und die Rahmenbedingungen ändern sich? (bspw. Ein Stück Metall innerhalb einer Spule). Mindestens im Reference-Manual solltest du zu den einzelnen Modi fündig werden, die werden dort alle lang und breit erklärt...
Es handelt sich um ein Ultraschall-Schwinggebilde. Bei der Messung wird ein Frequenzband durchfahren. sagen wir die Resonanzfrequenz liegt bei 20kHz, dann fangen wir bei einem Sinussignal der Frequenz f = 19500Hz an und fahren bis 20500Hz. Dazwischen muss ja die Resonanz liegen. Je nach Schwinggebilde ist der Amplitudengang/Phasengang breit oder schmalbandig. Der Phasensprung ist aber tatsächlich IMMER ein SPRUNG. Quasi fast unendlich steil...Habe dir mal ein Bild angehängt. Aber im uC erkenne ich das ja wenn ich weiss bei Resonanz habe ich Puls:Pause 1:1, denn irgendwann komme ich ja von 1,1:1 zu 1:1,1. Also von einem Wert über dem Mittwelwert auf einen Wert unter dem Mittelwert. Wir werden versuchen, mehrere Messfenster zu machen. Also ein Spektrum von 1kHz (s. o.) quasi grob mit 1Hz Schritten durchfahren, dann detektieren wir einen Phasensprung --> muss noch nicht genau sein, ist ja dann auf 1Hz genau. Dann haben wir einen schmaleren Bereich...fahren hier wieder durch. Dann ist es aber nur noch ein Spektrum von 2Hz, also 19997Hz bis 19999Hz (falls Sprung irgendwo dazwischen) --> nun in bspw. 10mHz Schritten...habe aber wieder irgendwo einen Punkt, an dem mir dieser Wert um einen Mittelwert kippt... Die Genauigkeit ändert sich aber deshalb ja nicht, wir nehmen immer einen kleineren Ausschnitt und haben somit mehr Messpunkte...irgendwann haben wir dann die Frequenz so genau bestimmt, wie wir es haben möchten.
Guckst Du: - Application Note 4013 (kurz "AN4013" genannt): STM32 cross-series timer overview - Application Note 4776 (kurz "AN4776" genannt) General-purpose timer cookbook - Und natürlich die 1000 Reference-Seiten Deines Prozessors ... Und dann viiiiiel lesen ... Damit konnte ich auf meinem STM32F4 Prozessor Dein oben beschriebenes Problem, nämlich eine Impulslängenmessung, lösen. Code müsste bei mir auch noch irgendwo rumfliegen, aber Du willst ja vermutlich nicht abschreiben, sondern selbst etwas lernen. Viele Grüße & good luck Igel1
Jetzt habe ich genau verstanden, was ihr wollt! Ja, so würde ich das auch lösen, mit den kleinen Wobbel-Schritten. Okay, im Grunde müsst ihr das Springen der Phasenlage detektieren Und das Springen passiert sehr abrupt. Naja, wenn ihr langsam genug wobbelt, schließt das doch den Tiefpass nicht aus? Nicht, dass es per Timer nicht auch wunderbar möglich wäre, keine Frage! Beim Tiefpass müsstet ihr lediglich auswertet, wenn sich die Spannung deutlich geändert hat. Dazu muss, wie gesagt, die Wobbelfrequenz so niedrig sein, dass die Verzögerung durch den Tiefpass ausreichend gering wird. Im Grunde brauchst du wohl zwei Timer. Einer für die absolute Frequenz (Trigger auf die steigende Flanke) und einer für die Pulsdauer (Trigger auf steigende und fallende Flanke). Es sei denn, die aktuelle Frequenz ist genau bekannt.
@Tobias G.: Problem schon gelöst? Oder noch Hilfe benötigt? Viele Grüße Igel1
Tobias G. schrieb: > In den Appli.-Notes steht nicht wirklich viel Hilfreiches. Doch, tut es: such mal nach "Gated mode" in AN4013. Gruß Igel1
Danke Andreas, habe in den AN nun auch was gefunden. Und ja, haben das Problem gelöst, habe nun schon erste Tests gemacht und mit einem Funktionsgenerator definierte Puls-Pausen-Verhältnisse draufgegeben...Ergebnis ist sehr erfreulich. Der uC misst sehr exakt. Vielen Danke für eure Hilfe!!!
Supi, freut mich, wenn wir helfen konnten. Wie habt Ihr es denn letzten Endes umgesetzt? Könnt Ihr Euren Code hier publizieren? Dann hätten alle etwas davon. Viele Grüße Igel1
Servus Andreas, werde ihn wenn ich heute Nachmittag Zeit finde hier einstellen, kein Problem.
Beitrag #5467637 wurde vom Autor gelöscht.
Habe noch einige Fehler entdeckt und jetzt auch größtenteils behoben. Sobald es wieder funktioniert stelle ich den Code mal hoch.
Okay - bin gespannt auf Deinen Code. Ich selber hab's auf die Schnelle noch nicht hinbekommen und mehr Zeit hatte ich bislang noch nicht (und meinen alten Code konnte ich auch nirgendwo mehr finden ...). Mein Ansatz wäre: Slave-Timer im Gated-Mode mit steigender Flanke starten und mit fallender Flanke wieder stoppen. Vorher und nachher jeweils den Zählerstand merken - die Differenz repräsentiert dann die Impulslänge. Hast Du es ähnlich gelöst oder hast Du einen anderen Ansatz verfolgt? Viele Grüße Igel1
Ja, habe allerdings das Signal auf einen Interrupt gelegt. Dieser holt mir den Zählerstand, übergibt ihn an eine variable und setzt mir eine andere Variable auf 1. In meiner infinity-Loop gehe ich über eine if-Schleife (falls dieser Variable 1 ist) in meinen Berechnungsalgorythmus. Dort wird abgefragt ob der Eingang high oder low ist. high --> zählerstand an high-Variable übergeben low --> zählerstand an low-Variable dann gibt es vier fälle: 1. es kam am Anfang eine falling flanke, dann eine rising flanke 2. oder anders herum 3. timer überlauf bei falling flanke 4. timer überlauf bei rising flanke je nachdem wird die Pulsdauer anders berechnet. dann werden ON-time und OFF-time voneinander abgezogen...variablen SINT!!!! dieser wert sollte zwischen +-2 liegen (Toleranz variabel...ja nach uC) dann wurde der Phasensprung detektiert....im anderen Fall würde ja ein deutlich größerer Wert als Differenz entstehen. Allerdings habe ich noch Probleme am Anfang, da werden immer erst 2 falsche werte berechnet, da die ON oder OFF time (eine jeweils) auf 0 ist und er zieht dann quasi 0 vom zählerstand ab, was ja nicht dem entspricht wie es wirklich ist....
Ich habe Deinen Text nun 3x an 3 verschiedenen Tagen gelesen, aber ich muss gestehen: ich verstehe ihn einfach nicht (mag an mir liegen, hilft aber nix - ich benötige eine besser verständliche Erklärung) Könntest Du ggf. nochmals beschreiben, was Du da tust? Und wie genau sieht Dein Signal aus (vor der Resonanzfrequenz, an der Resonanzfrequenz, nach der Resonanzfrequenz - inkl. Timings). Viele Grüße Igel1
Servus, hier mal die 3 Möglichkeiten. Pulse-Break 1to1: Resonanz Pulse-Break 3to1: vor Resonanz Pulse-Break 1to3: nach Resonanz Interrupt löst bei jeder Flanke aus und rechnet mir Timerwert aktuell minus Timerwert vergangen, speichert das. Nächste Flanke das Selbe. Sind die beiden Differenzen gleich --> Resonanz, sonst entweder darunter oder darüber. Wenn Timerwert 2 - Timerwert 1 == Timerwert 3 - Timerwert 2 bin ich in Resonanz.
:
Bearbeitet durch User
Ah soooo - jetzt verstehe ich ... Glückwunsch, dann hast Du das Problem ja scheinbar selber gelöst. Einzige Anmerkung meinerseits: Wenn Du die erste Flanke stets per Interrupt detektierst und die zweite Flanke per Polling (so jedenfalls habe ich Deine Beschreibung verstanden), so bekommst Du ein leicht verzerrtes Ergebnis, weil Du ja einige Taktzyklen verlierst, bevor Du überhaupt in der ISR landest und dort den Timerwert abspeichern kannst. Viele Grüße Andreas
Servus, nein, ein Interrupt kann als Rising | Falling definiert sein, dann löst er immer bei jedem Flankenwexhsel aus, d. h. beide Timerwerte werden in derselben Geschwindigkeit geholt. Mit einem Funktionsgenerator bei 1to1 Pulse-Break kommt man bis auf 0,66% hin mit einem Takt von 12MHz. Im Messgerät ist ein M4F verbaut...da liegt der Fehler dann bei 0,1%. Vielen Dank!
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.