Hi an alle,
meine Problemstellung sieht folgendermaßen aus:
Ich möchte den GPIO-Pin PA5 mit einem externen PWM-Signal belegen.
Bei dem Signal handelt es sich um eine übersetzte Abstandsmessung.
Der Sensor sendet also eine Falling-Edge aus, sobald die Messung
beginnt, und sendet eine Rising-Edge, sobald er das Signal, was er
ausgesendet hatte, wieder empfängt.
Soweit ich es verstanden habe, hat dieses Signal keine feste Frequenz.
Auf dem STM32 läuft FreeRTOS als Manager.
Der Plan ist, den Timer zu starten, sobald der Interrupt durch die Edge
erfolgt, und den gemessenen Zeit-Wert in eine Queue zu schreiben, die
dann später weiter verarbeitet wird.
Es folgt mein Code der Konfiguration. Ich vermute den Fehler beim
TIM_ITConfig.
Pieter schrieb:> ...und was für ein Problem hast Du????
Das hätte ich vielleicht erwähnen sollen :)
Wenn ich für TIM_IT (Arg2 von TIM_IT_Config) CCM1 bis 4 einsetze,
bekomme ich zwei verschiedene Assertion Failures von FreeRTOS zurück.
Falls sich jemand in FreeRTOS auskennt, bitte HIER schreien, dann kann
ich ins Detail gehen.
Ist denn meine Konfiguration oben prinzipiell richtig?
habe ja nicht alles im Kopf...und ferkel auch nicht in C...
TIM_ITConfig(
soll das was mit Timer-Interrupt-Config sein?
- TIM_IT_Update wird doch bei Über/Unterlauf ausgelöst.
Dann würde ich eine ISR erwarten, und wenn es die nicht gibt ...
Pieter schrieb:> habe ja nicht alles im Kopf...und ferkel auch nicht in C...>> TIM_ITConfig(>> soll das was mit Timer-Interrupt-Config sein?
Jau, soweit ich verstanden hab, sind die dafür zuständig, die Timer
auszulösen, wenn ein Rising/Falling-Edge am GPIO anliegt.. Hab grad nur
noch karussell im kopf..
> - TIM_IT_Update wird doch bei Über/Unterlauf ausgelöst.>> Dann würde ich eine ISR erwarten, und wenn es die nicht gibt ...
Hier die Funktion, die ich nicht mitgepostet hatte:
moin moin,
uint16_t captureValDiff;
ist sichergestellt, dass das eine statische Variable ist? (ausserhalb
ISR)
muss TIM_IT_Update nicht generell resettet werden?
VG
Pieter
Gehört nicht zum fred: das f_meter läuft bei mir unter Pascal :-) macht
aber nur Frequenz.
@Che
#define PWM_TIM_PRESCALER (84 - 1) // Wie wird der berechnet??
TIM2 arbeitet mit 2*42MHz als Takt, der counter arbeitet 0..83.
VG
Pieter
moin moin,
so, mein Prog läuft, allerdings brauche ich dazu keinen Interrupt.
Einfach TIM2_CCR1 und TIM2_CCR2 prüfen ob keine 0 und dann steht in
TIM2_CCR1 die Periodendauer und TIM2_CCR2 die Impulslänge.
Da ich TIM2_PSC auf 84-1 gesetzt habe, ist das Ergebnis in µs.
VG
Pieter
Pieter schrieb:> Da ich TIM2_PSC auf 84-1 gesetzt habe, ist das Ergebnis in µs.
Das ist ja langweilig! Das schafft ja schon ein ATmega ;-)
Aber vielleicht zeigst Du dem TO auch den Code.
Also ich bin jetzt umgestiegen auf TIM9 als neuen Timer.
Der hat eine Auflösung von 16 bit bei maximaler Frequenz von 84 MHz.
Mein Problem vorher war die Preemption-Priority bei den NVICs, die muss
bei FreeRTOS auf mindestens configMAX_SYSCALL_INTERRUPT_PRIORITY stehen.
Das ist allerdings sehr systemspezifisch, vielleicht hilfts ja doch
irgend einer armen Seele..
Ich würde allerdings gern verstehen wie ich meinen Prescaler berechne,
könnt ihr mir da weiterhelfen?
Viele Grüße,
Che
Che. schrieb:> Ich würde allerdings gern verstehen wie ich meinen Prescaler berechne,> könnt ihr mir da weiterhelfen?
Die Antwort darauf ist so einfach, daß das wohl eine Fangfrage ist?
Der Timer läuft wohl mit Internal Clock (CK_INT), welcher auf 84 MHz
eingestellt ist. Weitergeleitet geht dieser Takt über den Prescaler
(TIM9_PSC) an den eigentlichen Zähler: TIM9_CNT in Deinem Fall.
Dieser Prescaler steht nach einem Reset auf 0, was einem Teiler von /1
entspricht. Für ein anderes Teilungsverhältnis n lädt man den Prescaler
auf n-1. Soll TIM9_CNT mit 1 MHz getaktet werden (1 µs Auflösung), wird
PSC mit 84-1 = 83 geladen.
Dein oben verwendeter Faktor 100 ist Unfug.
> TIM_TimeBaseStructure.TIM_Prescaler = PWM_TIM_PRESCALER*100; //1 µS => PWM_TIM_PRESCALER mal 10
Im "Reference Manual" findest Du ein Blockschaltbild der diversen Timer
nebst ausführlicher Bechreibung.
Ok, danke m.n. für deine Antwort.
m.n. schrieb:> Dein oben verwendeter Faktor 100 ist Unfug.>> TIM_TimeBaseStructure.TIM_Prescaler = PWM_TIM_PRESCALER*100; //1 µS =>> PWM_TIM_PRESCALER mal 10
Faktor 100 ist nicht unbedingt "Unfug", aber anwendungsbedingt.
Faktor 10 passt besser. Das PWM Signal meines Sensors entspricht einer
LOW-Verhältnis von 10µs/cm, daraus folgt, dass Faktor 100 für
Meter-Messung eingesetzt wird.
Allerdings funktioniert der Sensor so wie in Bild 1.
Wenn ich jetzt für meinen Timer-Trigger
Che. schrieb:> Faktor 100 ist nicht unbedingt "Unfug", aber anwendungsbedingt.> Faktor 10 passt besser. Das PWM Signal meines Sensors entspricht einer> LOW-Verhältnis von 10µs/cm, daraus folgt, dass Faktor 100 für> Meter-Messung eingesetzt wird.
Bitte würfel Messung und Auswertung nicht durcheinander. Wenn Dir 1 µs
Auflösung reichen, stelle den Vorteiler auf 84 ein. Später kannst Du
dann nach Bedarf skalieren.
Andernfalls könnte es passieren, daß die 16 Bit breiten Register mit
Werten beschrieben werden, die aus einer 'Berechnung' mit Überlauf
stammen.
An welchen Eingang hast Du denn jetzt Dein Signal angeschlossen? Wenn Du
Timer9 verwendest, wären PA2 oder PE5 die möglichen Eingänge für
TIM9_CH1.
Im "Reference Manual" steht unter "PWM input mode" genau beschrieben,
welche Flanken auf welches Capture-Register wirken und wie der Zähler
zurückgesetzt wird, nachdem sein max. Wert in ein Capture-Register
geschrieben wurde. Dieser Wert ist die Periodendauer des
Eingangssignals. Im anderen Capture-Register steht die Pulsweite des
Signals.
Wichtig: pos. bzw. neg. Flanken haben ihr eigenes Capture-Register!
Einmal initialisiert können die aktuellen Daten direkt aus den
Capture-Registern gelesen werden. Wie Pieter schon geschrieben hatte,
braucht man dafür keinerlei Interrupts.
Sieh Dir die Abbildung zu "PWM input mode timing" an.
bin in eile...
> Da ich TIM2_PSC auf 84-1 gesetzt habe, ist das Ergebnis in µs.
bei TIM9 ist TIM9_PSC auf 168-1 zu setzen.
Die Null wird als Zustand mitgezählt!
In der Doku ist etwas versteckt...ist der APB-Teile auf 1 bekommen die
TimerCLK den doppelten Takt.
Beim INT würde ich für steigende Flanke freigeben, dann kommt am Ende
der Messung ein INT und man kann losrechnen.
So, Feierabend!
Hi m.n. und hi Pieter,
vielen Dank erstmal für eure Hilfe.
Ich konnte jetzt länger nicht an der Baustelle mit dem STM32 weiter
arbeiten, wegen Hardware-Problemen. Jetzt geht wieder alles und ich kann
weiter machen.
m.n. schrieb:> An welchen Eingang hast Du denn jetzt Dein Signal angeschlossen? Wenn Du> Timer9 verwendest, wären PA2 oder PE5 die möglichen Eingänge für> TIM9_CH1.
Genau, ich arbeite mit PA2.
m.n. schrieb:> Andernfalls könnte es passieren, daß die 16 Bit breiten Register mit> Werten beschrieben werden, die aus einer 'Berechnung' mit Überlauf> stammen.
Ich habe den Prescaler jetzt geändert und teile dann nachher seperat
durch 10 um auf meinen Wert zu kommen.
Pieter schrieb:> bei TIM9 ist TIM9_PSC auf 168-1 zu setzen.
Erledigt, die Abstandsmessung pendelt jetzt wieder um den richtigen
Zahlenwert zumindest.
Pieter schrieb:> Beim INT würde ich für steigende Flanke freigeben, dann kommt am Ende> der Messung ein INT und man kann losrechnen.
Du meinst mit INT den Interrupt, richtig? Wie gebe ich den denn für die
steigende Flanke frei?
Che. schrieb:> Pieter schrieb:>> Beim INT würde ich für steigende Flanke freigeben, dann kommt am Ende>> der Messung ein INT und man kann losrechnen.>> Du meinst mit INT den Interrupt, richtig? Wie gebe ich den denn für die> steigende Flanke frei?m.n. schrieb:> Im "Reference Manual" steht unter "PWM input mode" genau beschrieben,> welche Flanken auf welches Capture-Register wirken
... und wie man sie einstellt.