Hallo!
Ich habe eine Frage bezüglich der Dauer einer ISR bzw. der Dauer von
Befehlen ansich.
Ich entwickle mit IAR und einem STM32F103RBT6. Jetzt habe ich eine ISR
für den ADC geschrieben. Dieser löst einen IR aus, wenn er fertig
gewandelt hat. Ich habe dem Datenblatt von STM entnehmen können, dass
die Wandlung bei meiner Konfiguration (9MHz ADC Takt) etwa 1,6us dauert.
Daraus schließe ich, dass ich etwa 1,6us Zeit habe, um alles andere zu
tun.
Leider wirkt "alles andere" derzeit ganz schön viel. Meine Rechnung
sieht wie folgt aus:
72 MHz = 72.000.000 Takte/s
72.000.000 1s
---------- = -------
x 1,6us
1,6 x 10^-6 x 72 x 10^6 1,6 x 72 x
x = -------------------------- = ------------- = 115
1 1
Korrigiert mich, wenn ich falsch liege. Ich habe also zwischen zwei IRs
115 Takte, um andere Dinge zu tun. Ist das nicht extrem wenig? Ich hab
da so gar kein Gefühl für.
Was sind "andere Dinge"?
* Ich pulse zwei Dioden mit Hilfe der ISR des ADCs. Ich toggle diese
Dioden bei jedem dritten Aufruf der ISR.
* Außerdem akkumuliere ich sechs ADC Werte in einer Variable, die ich
dann nach 6 ISR Aufrufen auch wegschreiben muss.
* Mit den so erhaltenen Messwerten muss ich auch noch rechnen (Umfang
derzeit nicht ganz genau bestimmt). Klar, die Berechnungen würde ich
außerhalb der ISR ausführen. Dennoch bleibt das Zeitfenster ja fest
vorgegeben, wenn ich das richtig verstehe.
Ist das nicht alles ein wenig viel für das bisschen Zeit, was da bleibt?
Ich kann mir so gar kein Bild davon machen, wie lange ein Befehl dauert.
Gibt es Möglichkeiten das zu messen oder nachzulesen? Fragen über
Fragen...
Grüße
Sebastian
Nimm dir freie Pins und gib dir Testimpulse aus, z.B. am Anfang und am
Ende der ISR und am Anfang und am Ende der Routinen, wo du zweifelst,
wie lange die dauern.
Ein brauchbarer Oszi ist doch vorhanden oder?
Gruß vom Praktiker
>Ich habe eine Frage bezüglich der Dauer einer ISR bzw. der Dauer von>Befehlen ansich.
Das ist bei den STM32 nicht so einfach per Mathematik zu berechnen, wie
zB. bei den AVR. Die meisten Befehle werden in einen Zyklus
abgearbeitet. Die effektive Zeit ist von vielen Faktoren abhängig.
Waitstates Flash, Pipline-Einstellungen, Pipelinezustand, Linearität des
Codes usw.
Empfehlung: Pin toggeln und mit Oszi Zeit messen.
AD-Wandlung mit DMA wäre eventuell auch eine Alternative.
Nähres findest Du ua. in der STM Inside Guide,
unter http://www.hitex.com
Sebastian schrieb:> gewandelt hat. Ich habe dem Datenblatt von STM entnehmen können, dass> die Wandlung bei meiner Konfiguration (9MHz ADC Takt) etwa 1,6us dauert.> Daraus schließe ich, dass ich etwa 1,6us Zeit habe, um alles andere zu> tun.
In diesem Bereich landest du nur, wenn du mit maximaler Wandlungsrate
abtasten willst. Wozu dann aber DMA verwendet werden sollte.
Wenn es nur darum geht, beispielsweise alle Millisekunden zu messen,
dann sind diese 1,6µs völlig irrelevant, denn das Ergebnis der Wandlung
liegt bei Eintritt in die ISR bereits vor und verdampft auch nicht
sofort.
Wenn, wie hier angedeutet, die Abtastungen mit irgendwelchen
Pin-Aktivitäten einhergehen sollen, dann wär's bei engem Zeitrahmen
besser, sowohl diese Aktivitäten als auch die Abtastungen per Timer
auszulösen. Das lässt sich dann auch entsprechend präzise verzahnen,
ohne irgendwelche Befehlstaktzyklen und Flashwaitstates mitrechnen zu
müssen.
Sebastian schrieb:> Ich habe dem Datenblatt von STM entnehmen können, dass> die Wandlung bei meiner Konfiguration (9MHz ADC Takt) etwa 1,6us dauert.> Daraus schließe ich, dass ich etwa 1,6us Zeit habe, um alles andere zu> tun.
Aus Deiner Beschreibung wird nicht so ganz klar, ob Du zwischen der
Wandlungsdauer und dem Wandlungsintervall unterscheidest. Benötigst Du
wirklich alle 1.6µs einen neuen Wert? Das entspräche einer
Abtastfrequenz von 625kHz.
> Was sind "andere Dinge"?> * Ich pulse zwei Dioden mit Hilfe der ISR des ADCs. Ich toggle diese> Dioden bei jedem dritten Aufruf der ISR.
Und wer soll sich diesen Puls anschauen? Die Frequenz der LEDs beträgt
dann etwa 625kHz/(3*2) = 104.167kHz. Oder dient das nur der Messung?
> * Mit den so erhaltenen Messwerten muss ich auch noch rechnen (Umfang> derzeit nicht ganz genau bestimmt). Klar, die Berechnungen würde ich> außerhalb der ISR ausführen. Dennoch bleibt das Zeitfenster ja fest> vorgegeben, wenn ich das richtig verstehe.
Wenn Du erst nach jedem sechsten Wert rechnest, hast Du ja immerhin
6*(1.6µs - t_ISR) zur Verfügung.
--
Marcus
Guten Morgen!
Erst einmal vielen Dank für die zahlreichen Antworten. :-)
Also, was habe ich gestern noch getrieben? Ich habe versucht die Dauer
der ISR mit einem Oszi zu messen. Dafür habe ich zu Beginn der ISR einen
Pin ein- und zum Ende hin wieder ausgeschaltet. Das klappte bei 9MHz
ADC-Takt und einer Samplezeit von 1,5 Cycles hervorragend gar nicht. Auf
dem Oszi hab ich nur Brei gesehen (eine bessere Beschreibung fällt mir
als Informatiker nicht ein, sry). Also habe ich die Samplezeit mal
hochgeschraubt, da wurde es besser. Ich habe aber deutlich erkennen
können, dass das auf diese Weise erzeugte Signal unterschiedliche
Periodenlängen hatte. Wohl ein deutliches Zeichen dafür, dass ich nicht
jede Wandlung des ADCs mitkriege. Ich habe mit dem betreuenden Prof.
meiner Arbeit gesprochen. Der hatte halt etwas von 100kHz gebrabbelt,
wodurch für mich eben die Periodendauer von 10us festgelegt war. Da dann
der Cortex aber bei 6 Messungen pro Periode zwischen den ISR-Aufrufen
quasi keine bis negative Zeit zur Verfügung hat, haben wir uns nun drauf
geeinigt, dass 70kHz es durchaus auch tun könnten.
Vielleicht nochmal zum Rahmen, also warum ich das alles vorhabe.
Ich möchte mit Hilfe der zwei Dioden etwas messen. Ich dachte mir halt:
"Je öfter man messen kann, umso besser kann man später mitteln und damit
hoffentlich das Messergebnis verbessern". Ich will aber den Controller
nicht bis zum Anschlag auslasten. Es sollten irgendwie Leistungsreserven
da sein.
Zum Verfahren:
Zu Beginn leuchten beide Dioden mit 100% und irgendeiner Frequenz (jetzt
nicht mehr fest 100kHz). Das Licht, was von den Dioden zurückkommt, wird
von einer Fotodiode gemessen. Die liefert Werte, die vom ADC gewandelt
werden sollen. Je nachdem, welche Diode heller war, wird die andere
entsprechend geregelt. So erhalte ich eine Reihe von Messwerten, bei
denen ich dann später nur noch den richtigen Zwischenwert errechnen
muss.
Die ursprüngliche Idee war eigentlich, die LEDs mit zwei 50% PWMs zu
betreiben. Bei einem PWM im Duty-Cycle ein High-Pegel, bei dem anderen
eben ein Low-Pegel. Da hatte ich aber das Problem, dass ich nicht
wusste, wie ich den ADC dazu bringen sollte, kontinuierlich synchron mit
diesem PWMs zu messen. Daher entstand die Idee, den ADC in
Continuous-Mode zu verwenden, um die Dioden zu pulsen. So entfällt der
gesamte Synchronisierungsaufwand.
Ich hoffe, dass ich jetzt erstmal weiterkomme. Wenn jemand einen Tipp
hat, wie ich einen Timer verwenden kann, um das ganze stabil bei einer
bestimmten Frequenz umzusetzen, so wäre ich sehr dankbar. :-)
Liebe Grüße
Sebastian
Für Zeiten gibt es im uC Timer. Die heissen darum so weil Sie genau das
können. Du kannst im STM32 ohne Eingriff des Rechenknechts die ADCs vom
Timer starten lassen, die sind dann gleich auf die PWM synchronisiert.
Den DMA lässt Du Deine Messergebnisse ins RAM schreiben und erst wenn
der fertig ist bekommt der Rechner Arbeit. Also Mittelwerte bilden,
regeln,... langweilig wird Ihm angesichts der anfallenden Datenmenge
sicher trotzdem nicht. So zeitkritische Sachen kann und soll man besser
der Hardware überlassen.
Noch etwas zu dem Mittelwert: Warum glaubst Du dem ADC nicht einfach?
Ein ordentliches Leiterplattendesign, Kondensatoren und Filter wo Sie
nötig sind und dann misst der schon das was da ist. Viel interressanter
ist meist sich den besten Samplingzeitpunkt zu überlegen und auch
umzusetzen. Also dann wenn systembedingt eh grad keine Stöhrungen
(Schaltflanken,...) zu erwarten sind. Wenn man ein synchronisiertes
Design machen kann sollte man es auch nutzen.
Nichts gegen Mittelwerte, nutze ich auch viel, aber die konkrete
Notwendigkeit kann man doch mal hinterfragen.
Hauspapa schrieb:> Du kannst im STM32 ohne Eingriff des Rechenknechts die ADCs vom> Timer starten lassen, die sind dann gleich auf die PWM synchronisiert.
Hallo, Hauspapa,
genau da sehe ich nicht, wie es funktionieren soll. Ich bin leider
Neuling, was uCs angeht. :-( Kannst du mir dabei helfen? Also hast du
nen Tipp, wo ich da im Datenblatt oder sonstwo nachschauen kann? Das
wäre toll. Dass die Messung quasi ohne Rechenzeit funktioniert und in
Hardware abläuft, wäre ein Traum. Bedeutet ja schließlich auch, dass
zumindest dabei nix schief geht, weil es nichts ist, was ich
zusammengefuddelt habe. :-)
Das mit der Mittelwertbildung kommt daher, dass ich durch das Umschalten
in jeder dritten ADC-ISR quasi drei Zeitpunkte habe, an denen ich messen
kann. Oder anders gesagt: An denen gemessen wird (der ADC läuft ja im
Continuous-Mode). Da das eingehende Signal ein wenig phasenverschoben
ist (liegt an irgendeinem Filter, in der Elektrotechnik bin ich nicht
sehr bewandert), werde ich nur schwer den einen wirklich guten Zeitpunkt
zum messen abpassen können.
Auch später möchte ich Mittelwertbildung betreiben, da ich ein gewisses
Rauschen im Signal sicherlich nicht komplett rausrechnen kann.
Liebe Grüße
Sebastian
es gibt doch super App Notes zur Verwendung des ADC auf der homepage von
ST
da ist alles drin was du brauchst. Nur lesen musst du selbstständig.
http://www.st.com/mcu/familiesdocs-110.html
Ich hoffe das es inzwischen nicht mehr nötig ist. Trotzdem:
trocken aber nützlich ist da Reference Manual zum STM32.
Hat 1003 Seiten...
z.B. Kapitel 11.7 ADC Conversion on external Trigger und 10.3.7 DMA
request mapping. Zusammen mit library und den Beispielen von ST bringt
man das zum laufen. Braucht aber ein bischen Geduld bis man alles
beisammen hat.