Hallo zusammen, ich baue mir gerade mit einem STM32F103 eine kleine Schaltung auf, um analoge Spannungen betrachten zu können. Ähnlich einem "Oszi für Arme" habe ich mir mit Timer, ADC und DMA Circular Mode schon die Aufzeichnungsfunktionen realisiert, die Werte landen durch DMA in einem Array und werden (derzeit) einfach endlos wie ein Ringpuffer überschrieben. Nehmen wir mal an, dieser hat 512 Elemente. Nun würde ich gerne auf wiederholende Signalverläufe triggern, um die Aufzeichnung irgendwann zu stoppen und das Array auf ein Grafikdisplay zu plotten, bevor eine neue Runde startet. Logischerweise sollte der Triggerpunkt einigermaßen mittig liegen. Wenn ich jetzt jeden ADC-Wert mittels Interrupt auf überschreiten der Triggerschwelle prüfen muss und ab da z.B. auf 256 Zähle und dann die Aufnahme händisch stoppe, wäre dieses Soll zwar erfüllt und das Bild mittig, aber die CPU hat ohne Ende zu tun und die DMA ist irgendwo auch sinnlos. Hat jemand eine Idee, wie man das eleganter lösen könnte? Ich würde gerne auf zu viele Interrupts verzichten. Meine Idee war: Den Analog Watchdog verwenden, um die Werte zu beobachten und ein Interrupt auszulösen, sobald die Triggerbedingung erfüllt ist. Dabei deaktiviert sich der Watchdog selbst, sodass nicht erneut getriggert wird. In der ISR aktiviere ich einen weiteren Timer als Zähler, der seinen Takt vom Update-Ausgang des ersten Timers (der, der den ADC auslöst) erhält. Der Reload-Wert wird auf 256 gesetzt. Sobald nun dieser Timer überläuft, sind (in der Theorie) 256 Werte seit der Triggerung aufgenommen worden und das Bild mittig. Allerdings läuft die Timer->ADC->DMA Geschichte während der ISR ja fröhlich weiter, sodass je nach Samplerate wohl mehr als 256 Werte genommen werden. Das Bild ist dann leicht aus der Mitte, aber die Verzögerung wäre ja für alle weiteren Durchläufe reproduzierbar. Trotzdem: Hat jemand eine Idee, wie man das eleganter lösen könnte? Vielleicht sogar so, dass ohne Zutun der CPU getriggert wird und dann noch genau 256x gewandelt wird, bis die Aufnahme stoppt?
>wäre dieses Soll zwar erfüllt und das Bild >mittig, aber die CPU hat ohne Ende zu tun ROFL. Das langweilt deine CPU vermutlich nur.
Die Werte in zwei/drie Buffer schreiben. Sobald das Ereignis kommt, wird den actuelle Buffer+1 weiter gefullt. Jetzt haben sie alle Daten gespeichert, und is est nur noch ein Problem von Wiedergabe. Ubrigens ist den STM32 F3 hier noch besser geignet : hat OPAMP + Hardware comparator. MFG
Robin S. schrieb: > die Werte landen durch DMA in einem > Array und werden (derzeit) einfach endlos wie ein Ringpuffer > überschrieben. Nehmen wir mal an, dieser hat 512 Elemente. Tja, so ein DMA kann eben nur Daten herumschaufeln, aber nicht selbst bewerten. Das kann nur die CPU per geeignetem Programm. Also wenn man diesen Gedanken konsequent weiterdenkt, dann kommt nur in Frage, ohne DMA zu arbeiten, auch ohne Interrupts. Stattdessen in der Grundschleife in main mit so wenig Code wie möglich den ADC abzufragen, dessen Werte in den Ringpuffer zu schreiben und zu bewerten. Aber nimm für sowas lieber einen Cortex M4F, denn du willst ja deine Werte auch noch skalieren, bevor du sie auf das Display losläßt. Die hohe Schule wäre so ein 200 MHz LPC43xx mit zwei CPU's drin. Eine macht nur die ADC-Abfragen und die andere die Bedienung, Displayansteuerung sowie Berechnungen. W.S.
Hi Robin, welchen F103 setzt Du denn ein? Bei einem, ggf. pinkompatiblen, F40x @ 168MHz würde ich für Deine Anwendung kein großes Problem sehen. Dessen Interrupt-Latenzzeiten sind zwar nicht berauschend, allerdings stehst Du so schnell in der ISR, dass Du innerhalb ein/zwei Samplezeiten einen Timer aktiviert bekommst. Oder, bei entsprechend großen Puffern, Dir einfach nur einen Zeitstempel aus einem freilaufenden Timer merkst und daraus später die Bildlage zusammenbaust. Dasselbe Konzept sollte auch bei einem F1 funktionieren, ggf. mit ca. der doppelten Latenzzeit. OHNE CPU und ohne Zusatzhardware habe ich beim F40x auf die Schnelle keine Lösung gefunden, da der Analog Watchdog scheinbar nur in den NVIC läuft und nicht direkt an die Timer gehängt werden kann. OHNE CPU und Zusatzhardware könnte so aussehen, dass Du Dir einen Komparator an einen Timer-Kontrollpin hängst. Triggerschwelle wird mit DAC oder PWM eingestellt, der Vergleichseingang hängt am Signal. Cheerio, marcus
Danke an alle für die Antworten, > Das langweilt deine CPU vermutlich nur. Möglich, aber bei abertausenden von Interrupts/s sehe ich mich gerne um, ob bei diesen Hardware-Möglichkeiten nicht ne intelligentere Lösung denkbar ist. W.S. schrieb: > dann kommt nur in Frage, ohne > DMA zu arbeiten, auch ohne Interrupts. Stattdessen in der Grundschleife > in main mit so wenig Code wie möglich den ADC abzufragen, dessen Werte > in den Ringpuffer zu schreiben und zu bewerten. Das wäre mein letzter Ausweg, mal schauen. Markus H. schrieb: >welchen F103 setzt Du denn ein? >OHNE CPU und ohne Zusatzhardware habe ich beim F40x auf die Schnelle >keine Lösung gefunden, da der Analog Watchdog scheinbar nur in den NVIC >läuft und nicht direkt an die Timer gehängt werden kann. Es handelt sich um den STM32F103C8T6, den man bei Reichelt günstig bekommen kann (deshalb ;-) ). Hmm, meine Vorstellung war schon, mit dem Analog Watchdog einen Interrupt auszulösen, in dem ich dann einen zweiten Timer aktiviere, der bei jedem Update-Event des ADC-Timers +1 hochzählt. Da ist eben das Problem der Latenz, wie auch beim von dir beschriebenen Vorgehen. Ich werde vielleicht einfach mal testen, wie gravierend das ist. >OHNE CPU und Zusatzhardware könnte so aussehen, dass Du Dir einen >Komparator an einen Timer-Kontrollpin hängst. DAS ist eine sehr gute Idee! Die Möglichkeit halte ich mir auf der Platine in jedem Fall mal offen. Nur stellt sich da halt ebenfalls die Frage, wie man geschickt das Zählen beginnt. Wenn ich mit dem Pin wieder nur in eine ISR gehe, die dann einen Zähler aktiviert, der (hardwareseitig) mit dem ADC-Timer verbunden ist, sind wir wieder beim gleichen Problem wie beim Watchdog, oder? Kann natürlich sein, ich übersehe da was, ich bin noch dabei, mir einen Überblick über die ganzen Möglichkeiten zu verschaffen.
Robin S. schrieb: > Markus H. schrieb: >>welchen F103 setzt Du denn ein? >>OHNE CPU und ohne Zusatzhardware habe ich beim F40x auf die Schnelle >>keine Lösung gefunden, da der Analog Watchdog scheinbar nur in den NVIC >>läuft und nicht direkt an die Timer gehängt werden kann. > > Es handelt sich um den STM32F103C8T6, den man bei Reichelt günstig > bekommen kann (deshalb ;-) ). > Hmm, meine Vorstellung war schon, mit dem Analog Watchdog einen > Interrupt auszulösen, in dem ich dann einen zweiten Timer aktiviere, der > bei jedem Update-Event des ADC-Timers +1 hochzählt. Da ist eben das > Problem der Latenz, wie auch beim von dir beschriebenen Vorgehen. Ich > werde vielleicht einfach mal testen, wie gravierend das ist. Schau mal in die entsprechende Doku und berichte, wieviel Taktzyklen der NVIC/ARM für den ISR Ansprung braucht. Wenn Deine MCU mit 72MHz läuft, kann Du den Jitter abschätzen. >>OHNE CPU und Zusatzhardware könnte so aussehen, dass Du Dir einen >>Komparator an einen Timer-Kontrollpin hängst. > DAS ist eine sehr gute Idee! Die Möglichkeit halte ich mir auf der > Platine in jedem Fall mal offen. Nur stellt sich da halt ebenfalls die > Frage, wie man geschickt das Zählen beginnt. Wenn ich mit dem Pin wieder > nur in eine ISR gehe, die dann einen Zähler aktiviert, der > (hardwareseitig) mit dem ADC-Timer verbunden ist, sind wir wieder beim > gleichen Problem wie beim Watchdog, oder? > > Kann natürlich sein, ich übersehe da was, ich bin noch dabei, mir einen > Überblick über die ganzen Möglichkeiten zu verschaffen. Ich schrieb "Timer-Kontrollpin" - sprich Du machst das direkt in Hardware. Stichworte: Input-Capture oder ETR. Insgesamt ist beim STM immer der Trick rauszufinden, wie man die Peripherie sinnvoll verwursten kann. Der NVIC ist mächtig, aber verhältnismäßig träge. Der ARM-Core bringt eine hohe mittlere Rechenleistung, hat aber, insbesondere mit GCC, hohe Latenzen bei Kontextwechseln. Mit Assembler sähe das anders aus. ;)
Marcus H. schrieb: > Schau mal in die entsprechende Doku und berichte, wieviel Taktzyklen der > NVIC/ARM für den ISR Ansprung braucht. Wenn Deine MCU mit 72MHz läuft, > kann Du den Jitter abschätzen. Ich tue mich schwer, die spezifische Info bei ST zu finden, allerdings ist für den Cortex M3 bei ARM selbst zu lesen, dass nominell 12 Takte gebraucht werden, um eine ISR anzuspringen. Angesichts dessen, dass meine Signale nur im kHz-Bereich liegen, werde ich der Einfachkeit halber mal ausprobieren, wirklich die Werte von der CPU überwachen zu lassen. > Ich schrieb "Timer-Kontrollpin" - sprich Du machst das direkt in > Hardware. > Stichworte: Input-Capture oder ETR. Darin werde ich mich ebenfalls mal einarbeiten, spätestens nachdem ich mal die Software-Lösung probiert habe. Danke!
Robin S. schrieb: > Ich tue mich schwer, die spezifische Info bei ST zu finden, allerdings > ist für den Cortex M3 bei ARM selbst zu lesen, dass nominell 12 Takte > gebraucht werden, um eine ISR anzuspringen. 12 Takte Entry Latency, wenn der gewünschte Interrupt eine ausreichende Priorität hat. Zuzüglich der Kram, den der Compiler noch macht. Schließlich noch 10 Takte Exit Latency. An dieser Stelle darfst Du auch mal ins Disassembly schauen. Du kannst die kompletten ISR-Latenzzeiten testen, indem Du von extern triggerst und in der ISR einen GPIO setzt. Ohne groß aufzupassen sollten da Latenzzeiten unter 1us rauskommen - bei Verwendung der ST-Bibliotheken vor HAL. Lektüre: STM32F103x8 DocID13587 Datasheet RM0008 Reference Manual PM0056 Cortex M3 Sämtliche Peripheriedoku, inkl. / NVIC ... Die französische Originaldoku wurde bereits ins Englische übertragen und sehr übersichtlich in ca. 50 Dokumenten und auf ca. 10000 Seiten kurz zusammengefasst. ;)
Für Fälle, wo der DMA kontinuierlich laufen und gleichzeitig auf die gelesenen/geschriebenen Daten zugegriffen werden muss gibt es den "Half-Transfer Interrupt". Sobald dieser aktiv ist, kann gefahrlos die "erste Hälfte" der Daten bearbeitet werden. Worauf natürlich weiterhin geachtet werden muss ist, dass die Bearbeitung der Daten beendet ist, bevor der DMA die besagte Hälfte wieder überschreibt... Diverse F4-Derivate hatten soweit ich mich entsinne auch mal einen "Double Buffer" Mode. Damit dürften ähnliche Dinge machbar sein.
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.