Hi,
ich habe hier einen STM32F, der mit 180 Mhz läuft und in unregelmäßigen
Abständen eine Flanke an einen GPI erhält. In meinem Code führt jede
dieser Flanken zu einem Interrupt.
Jetzt würde ich gerne die Zeit zwischen zwei solchen Interrupts messen,
am liebsten in der Anzahl der Taktzyklen die seit dem letzten mal
vergangen sind.
Wie geht das?
Danke!
Schnapp dir einen der Timer, lass den schnellstmöglich laufen, pack dein
Signal an einen dazu passenden Input-Capture Pin, konfiguriere den auf
die Flanke, die dich interessiert...
W.S. schrieb:> Indem du selbige Takte zählst und dir von Ereignis zu Ereignis merkst.
Den Systemtakt kann ich ja wohl kaum selber zählen ohne dass der Zähler
bei jedem Interrupt unterbrochen werden würde.
Aber falls du mich auf ein Register aufmerksam machen möchtest, welches
die Taktzyklen zählt - gerne, welches ist es denn?
Spacer schrieb:> Den Systemtakt kann ich ja wohl kaum selber zählen ohne dass der Zähler> bei jedem Interrupt unterbrochen werden würde.
Du solltest erstmal mit deutlich kleineren uC anfangen,
PIC10, PIC12, sowas,
damit Grundlagen erlernen.
Und erst später in die Astronautentechnik einsteigen.
Spacer schrieb:> gerne, welches ist es denn?
Eines der Timer-Zählerregister, mit Prescaler=1, und natürlich die Clock
Configuration so einstellen, dass der Timer auch die volle Frequenz
abbekommt.
Tu dir einen Gefallen und nimm einen der 32-Bit-Timer. Sonst ist die CPU
ständig am Overflow-Mitzählen.
Spacer schrieb:> Den Systemtakt kann ich ja wohl kaum selber zählen ohne dass der Zähler> bei jedem Interrupt unterbrochen werden würde.
Aufgrund deiner Angabe zu 180 Mhz gehe ich von einem STM32F4 aus, da ist
ein Cortex M4 Kern drin. Dieser hat einen Zähler namens DWT_CYCCNT, der
die CPU Takte zählt.
Siehe dazu die Diskussion
https://stackoverflow.com/questions/36378280/stm32-how-to-enable-dwt-cycle-counter
Stefan ⛄ F. schrieb:> Aufgrund deiner Angabe zu 180 Mhz gehe ich von einem STM32F4 aus, da ist> ein Cortex M4 Kern drin. Dieser hat einen Zähler namens DWT_CYCCNT, der> die CPU Takte zählt.
Danke, gibt also doch nicht nur Selbstdarsteller hier :-)
Εrnst B. schrieb:> Eines der Timer-Zählerregister, mit Prescaler=1, und natürlich die Clock> Configuration so einstellen, dass der Timer auch die volle Frequenz> abbekommt.
Das geht gar nicht, so schnell ist die Peripherie nicht. Es geht um 180
MHz!
Stefan ⛄ F. schrieb:> Das geht gar nicht, so schnell ist die Peripherie nicht.
Mag sein, hatte da wohl einen anderen F4 im CubeMX offen.
Wird mit halbem Clock, also 90MHz am Timer trotzdem noch
genauer/jitterärmer laufen als in der ISR den Cyclecounter zu Fuß
auszulesen.
Εrnst B. schrieb:> Tu dir einen Gefallen und nimm einen der 32-Bit-Timer. Sonst ist die CPU> ständig am Overflow-Mitzählen.
Ach nee, wieder ein Bedenkenträger der am Tun dranmachen ist.
Spacer schrieb:> eine Flanke an einen GPI erhält.
Geschick ist immer, einen Pin zu verwenden, der als Capture-Eingang für
einen beliebigen Timer genommen werden kann. Das ergibt die beste
Auflösung für die Messungen.
Beispiele für die reine Zeitmessung habe ich nicht, sondern nur im
Zusammenhang mit Frequnezzählern, die neben den Zeiten auch die
Ereignisse zählen und
auswerten:http://mino-elektronik.de/fmeter/fm_software.htm#bsp_f730
Vielleicht findest Du hier für Deine CPU geeignete Programme. Beachte
die Dateien "F2_messung.c" und hier die Interrupts der verwendeten
Timer. In einem werden nur die Überlaufe gezählt und im anderen die
Ereignisse und dazu die genauen Zeitpunkte inkl. Überläufe.
Ich habs so gemacht: ein Timer konfiguriert mit zwei Input capture
direct mode Kanälen, reset mode und als Trigger source TI1FP1 ausgewählt
(siehe Bild).
Dann brauchst Du nur im Programm
diff = TIM2->CCR3;
abfragen und bekommst direkt die Take ausgegeben.
Habs ohne Interrupt, aber du kannst natürlich auch ein Interrupt
starten, wenn die Messung abgeschossen ist, oder das Ganze über DMA
laufen lassen.
Gruß
Hermann S. schrieb:> und bekommst direkt die Take ausgegeben.
sh. oben, den Fehler hatte ich auch. bei 180MHz Sysclk und max. 100 MHz
Timer-clock muss man die nochmal auf 90MHz halbieren, kriegt also nur
"Doppeltakte" aus dem Timer ausgelesen.
Mit ein paar kleinen Einschränkungen kann man mit dem DWT->CYCCNT
ziemlich genau messen:
- der Pin-Interrupt muss der einzige Interrupt sein
- das Hauptprogramm darf keine Divisions-, FP- und LDM/STM-Befehle
benutzen
- der Stack muss immer aligned-8 sein
- das gesamte Programm muss in den Cache passen oder Cache und Prefetch
müssen abgeschaltet werden
- der Counter muss zu Beginn der ISR gelesen werden
Von der Flanke am Pin bis zum Lesen des Counters vergehen viele
Taktzyklen, aber das bei jeder Flanke, also egal -- solange es immer
gleich viele sind. Ein wenig Jitter entsteht durch unterschiedlich lange
Befehle im Hauptprogramm, daher die Einschränkungen. Normalerweise
hängen die Pins am AHB oder noch direkter an der CPU. Solange AHB-Clock
= HCLK ist, dürfte da kein weiterer Jitter dazu kommen.
Ja gut, ich hab "nur" nen F103, hab also keine 180 MHz, Clock und Timer
sind auf der gleichen Frequenz, bei mir passt das auch, wenn ich die
Takte dann auf die Frequenz umrechne.
Wenn man das aber weiß mit den "Doppeltakten", kann man das ja
entsprechend gegenrechnen?!
Erich schrieb:> Spacer schrieb:>> Den Systemtakt kann ich ja wohl kaum selber zählen ohne dass der Zähler>> bei jedem Interrupt unterbrochen werden würde.>> Du solltest erstmal mit deutlich kleineren uC anfangen,> PIC10, PIC12, sowas,> damit Grundlagen erlernen.> Und erst später in die Astronautentechnik einsteigen.
Ich find die STM32´s sind in Kombination mit der CubeIDE doch recht gut
auch für "Einsteiger" geeignet. Man muss sich allerdings doch etwas
einlesen, aber ich denke das muss man bei anderen Mikrocontrollern auch.
Finds halt recht einfach dass man die Hardware nicht selbst
programmieren muss.
Es ist schon eine Weile her das ich einen STM32 programmiert habe, aber
ich meine daß es da eine Standardbibliothek von ARM (oder doch von ST?)
gibt. Irgendwas mit SysClock, SysTick, oder so.
Dafür braucht er jedenfalls keinen extra Timer zu opfern.
Wühlhase schrieb:> Dafür braucht er jedenfalls keinen extra Timer zu opfern
Mit dem Timer bekommt man halt Auflösung = Genauigkeit = 1/90Mhz hin.
Mit dem händischen Auslesen des Cyclecounters in der ISR ist die
Auflösung doppelt so gut, aber die Genauigkeit schlechter bis
katastrophal schlecht.
Je nachdem ob gerade aus dem Flash oder aus dem Ram/cache gearbeitet
wird, ob es andere ISRs mit evtl. sogar höherer Priorität gibt, ob das
Hauptprogramm "böse", langlaufende Befehle enthält usw. dauert es
unterschiedlich lange, bis die ISR überhaupt angesprungen wird...
Wühlhase schrieb:> SysClock, SysTick,
die sind m.W. nochmal runtergeteilt, und hätten ansonsten dasselbe
Problem.
Wühlhase schrieb:> Dafür braucht er jedenfalls keinen extra Timer zu opfern.
Welche Aufgabe wäre es denn Wert, einen der unzähligen Timer zu
"opfern"?
Mal direkt gesagt: ich verstehe nicht, wie man in heutigen Tagen noch so
dämliche Vorschläge machen kann :-(