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!
Spacer schrieb: > Wie geht das? Indem du selbige Takte zählst und dir von Ereignis zu Ereignis merkst. W.S.
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...
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
Stimmt, das kann sein, ich habe das damals für Zeiten im Millisekundenbereich benutzt.
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 :-(
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.