Hallo,
ich verwnede ein STM32VL Discovery Board.
Ich versuche gerade die Frequenz eines Eingangssingnales zu messen.
Signal liegt auf Port PA2 an und hat eine Frequenz zwischen 0Hz und 500
Hz.
Ich verwende zum messen der Zeit zwischen Rising Edge und Falling Edge
den Timer15 CH1.
Das Funktioniert auch soweit. Sobald eine Flanke auf dem Signal erkannt
wird, wird das Capture Event ausgelöst und die ISR ausgeführt.
Mein Problem: Die Werte haben überhaupt nichts mit der gemessenen
Frequenz zu tun. Gemessene Frequenzen leigen zwischen 366Hz und
280KHz!!!
Meine Vermutung ist, dass es sich um nicht abgefangene Timer Überläufe
des Registers handelt. Wenn ich das in der Initialisierung richtig
verstanden habe, dann läuft der Timer mit dem vollen 24Mhz.
Register geht bis 65535 => 2,73062ms bis zum Überlauf => 366Hz, woher
vermutlich auch die Untergrenze der gemessenen Frequenz herkommt.
Meine Frage:
Wie kann ich Timerüberläufe Abfangen?
Kann ich den Timer auch auf eine andere Frequenz einstellen, mit der er
den Register wert hochzählt, dass es gar nicht zu einem Timer überlauf
kommt?
Anbei mein Code:
Initialisierung:
hm..
ich vermute mal, du hast die Variablen zur Auslesung der Timerwerte als
unsigned Integer deklariert ?
Eine Überlaufdifferenz kannst du aber nur in einem (signed) int
berechnen.
... Ich weiß nicht welchen Compiler du verwendest aber die Bedingung
nach dem ersten "else" kannst du normalerweise weglassen. Außerdem seh
ich gerade das du in der If Anweisung die Bedingung "CaptureNumber = 1"
dahingehend änderst das sie auch im Else-Zweig ausgeführt wird...
Hi Philipp,
Philipp schrieb:> Ich verwende zum messen der Zeit zwischen Rising Edge und Falling Edge> den Timer15 CH1.
das ergibt aber nicht die Frequenz...sondern die Impulszeit
von dem Signal
wenn du die Frequenz messen willst, solltest du nur auf die Hi-Flanke
triggern (oder nur auf LO-Flanke)
Philipp schrieb:> Kann ich den Timer auch auf eine andere Frequenz einstellen, mit der er> den Register wert hochzählt, dass es gar nicht zu einem Timer überlauf> kommt?
beim STM32F4 gibt es den Befehl
damit wird der Vorteiler auf den Wert "83" eingestellt
und "Nerd" hat recht, in der ISR kannst du schreiben
1
if(CaptureNumber == 0)
2
{
3
....
4
CaptureNumber = 1;
5
}
6
else {
7
....
8
CaptureNumber = 0;
9
}
es gibt ja nur zwei möglichkeiten
und noch was (mit TIM15) hab ich noch nichts gemacht
aber bei TIM2 bis TIM5 muss der GPIO auf AF gestellt werden
und per
Hallo Uwe und Nerd,
danke für eure Hilfe,
Uwe B. schrieb:> beim STM32F4 gibt es den Befehl> TIM_PrescalerConfig(TIM2, 83, TIM_PSCReloadMode_Immediate);
Das sieht doch mal Vernünftig aus. Genau so einen Befehl habe ich
verzweifelt gesucht.
Werde ich gleich mal ausprobieren sobald ich dazu komme und berichten,
ob ich zum gewünschten Ergebnis gekommen bin.
Uwe B. schrieb:> und noch was (mit TIM15) hab ich noch nichts gemacht> aber bei TIM2 bis TIM5 muss der GPIO auf AF gestellt werden> und perGPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2);>> mit dem Timer verbunden werden....> ...braucht man das bei TIM15 nicht ?
Das habe ich nicht gebraucht. Wie gesagt, wird die ISR aufgerufen,
sobald eine Flanke auf dem Signal ist. Obwohl laut Datenblatt CH2 von
TIM15 auf PA2 mit Alternate Function declariert ist.
Werde ich auch mal ausprobieren, wie sich dieser Befehl auswirkt.
Grus Philipp
Hallo Uwe,
also der Befehl
Uwe B. schrieb:> TIM_PrescalerConfig(TIM2, 83, TIM_PSCReloadMode_Immediate);
hat den gewünschten erfolg gebracht. Ich kann jetzt auch deutlich
langsamere Frequenzen bestimmen.
Das mit dem GPIO_PinAFConfig ist mir ein Rätsel, da es kein Unterschied
macht, ob ich diesen Befehl verwende oder nicht.
Weiß jemand genaueres darüber, was es damit aufsich hat.
Gruß Philipp
Ist zwar für den F4xx und Timer9, aber vielleicht kannst Du den Code für
Dich anpassen. Beitrag "reziproker Frequenzzähler mit STM32F4Discovery"
Die Variablen zur Berechnung sind vom Typ unsigned (uint16_t, uin32_t)
damit die Überläufe richtig berechnet werden.