Forum: Mikrocontroller und Digitale Elektronik Resourcenschonende µS Quelle für Cortex-M4 (STM32F4xx)


von lion (Gast)


Lesenswert?

Hallo Zusammen,

ich benötige für ein Projekt eine µS Quelle die nicht zu genau sein 
muss. (Es dürfte natürlich auch eine höher frequente Quelle sein, µS ist 
das was ich mindestens möchte).

Im Endeffekt geht es darum Ereignisse zu protokollieren. Als Zeitstempel 
soll hier der Wert in µS nach dem Einschalten / Hochlauf des µC sein. 
Einen Timer-Interrupt der alle µS eine Variable hochzählt dafür zu 
opfern ist mir aus Performance Gründen zu schade. Extra Peripherie dafür 
ist nicht vorgesehen, es soll also mit Bordmitteln auf dem Chip 
funktionieren.

Gibt es eine gute Möglichkeit / Quelle um so einen µS Wert zu erhalten?

Als Basis für das Projekt dient ein Cortex-M4 (STM32F4xx).

Vielen Dank schon mal!

von holger (Gast)


Lesenswert?

>Einen Timer-Interrupt der alle µS eine Variable hochzählt dafür zu
>opfern ist mir aus Performance Gründen zu schade.

Für unbenutze Timer oder Rechenzeit gibt es kein Geld zurück;)
Und wenn dein Zeitstempel länger als 1 1/2 Stunden aufnehmen
können muss, brauchst du sowieso schon einen Zähler > 32Bit.

von Jim M. (turboj)


Lesenswert?

Der Core enthält auch ein paar Counter im Debug Peripherial, die man 
auch aus dem Programm heraus auslesen kann. Außerdem gibt es ja auch 
noch den SysTick.

Aaaber: Dort wird in den diversen Stromsparmodi gerne mal der Takt 
angehalten...

Ein Timer oder RTC ist dann besser geeignet.

von Jim M. (turboj)


Lesenswert?

holger schrieb:
> Für unbenutze Timer oder Rechenzeit gibt es kein Geld zurück;)

Bei Batteriebetrieb würde ich das nicht unterschreiben, ausgeschaltete 
Peripherials ziehen kein Strom - eingeschaltete dagegen schon.

von Jobst M. (jobstens-de)


Lesenswert?

lion schrieb:
> Wert in µS

Warum so kompliziert?

1µS = 1MΩ


Jim M. schrieb:
> Bei Batteriebetrieb würde ich das nicht unterschreiben, ausgeschaltete
> Peripherials ziehen kein Strom - eingeschaltete dagegen schon.

Na, dann schalten wir die interne Hardware ab und setzen eine externe 
daneben. Wie stromsparend.



Na, es wird doch wohl ein Zähler/Timer integriert sein, welcher mittels 
prescaler irgendwo bei 1MHz zählt!? Evtl. sogar bis 32 Bit, dann 
brauchst Du Dich nur alle 1,2h in einem IRQ darum zu kümmern.


Gruß

Jobst

von Lutz (Gast)


Lesenswert?

Na irgendein Timer läuft ja normalerweise sowieso. Und Timerinterrupt 
zum Hochzählen? Warum? Timer_Ende - Timer_Start = Verstrichene Zeit. 
Überlauf natürlich beachten.

Allerdings: Wenn du µs nach dem Einschalten mit onboardmitteln messen 
willst, ist es sowieso doof: Deine Hardware rennt ja erst sehr viele µs 
nach dem POR los...

von Axel S. (a-za-z0-9)


Lesenswert?

Jim M. schrieb:
> holger schrieb:
>> Für unbenutze Timer oder Rechenzeit gibt es kein Geld zurück;)
>
> Bei Batteriebetrieb würde ich das nicht unterschreiben, ausgeschaltete
> Peripherials ziehen kein Strom - eingeschaltete dagegen schon.

Ach was.

Wenn irgend etwas jede Mikrosekunde hochzählen soll, dann
ist ein Hardware-Timer mit Sicherheit das stromsparendste.

von lion (Gast)


Lesenswert?

Hallo Zusammen,

danke für eure Antworten.

Der Offset zwischen Versorgungsspannung liegt an und Programm läuft ist 
nicht so entscheidend, es geht tatsächlich darum einen Zusammenhang zu 
erkennen. Also Event A kommt zum Beispiel bei 237µs und Event B kommt 
bei 523µs. Da es aber sehr viele Events gibt und die auch sehr 
sporadisch auftreten können, brauche ich einen Timer der absolut 
arbeitet und konstant hochzählt.

Dafür würde ich natürlich auch einen uint64_t opfern und komme damit bis 
weit weit weit über meine Lebenserwartung hinaus :)

Nichts desto weniger tun mir die 100 kHz IRQ einfach so zu verbraten 
schon ziemlich weh.


So wie ich der Diskussion entnommen habe wäre ein Vorschlag einfach 
einen Timer mit 100 kHz hochzählen zu lassen der dann z.B. alle Sekunde 
(das wäre ok :)) einen IRQ auslöst.

Jeder IRQ erhöht dann einen Offset-Wert um 1*1000*1000 µs.

Tritt ein Event auf, nehme ich den aktuellen Zählerstand des Timers + 
den Offset als absoluten Zeitstempel. Haut das so hin?

Viele Grüße!

von Jobst M. (jobstens-de)


Lesenswert?

lion schrieb:
> Tritt ein Event auf, nehme ich den aktuellen Zählerstand des Timers +
> den Offset als absoluten Zeitstempel. Haut das so hin?

Ja, prinzipiell geht das so. Wäre mir allerdings zu kompliziert.

Ich würde einfach bei jedem Zählerüberlauf (=IRQ) eine Variable 
incrementieren. Zähler und Variable aneinandergehängt ergeben eine 
fertige Binärzahl.


Gruß

Jobst

von Gerd E. (robberknight)


Lesenswert?

lion schrieb:
> einen Timer mit 100 kHz hochzählen zu lassen der dann z.B. alle Sekunde
> (das wäre ok :)) einen IRQ auslöst.
>
> Jeder IRQ erhöht dann einen Offset-Wert um 1*1000*1000 µs.
>
> Tritt ein Event auf, nehme ich den aktuellen Zählerstand des Timers +
> den Offset als absoluten Zeitstempel. Haut das so hin?

so ungefähr.

Bei diesem Vorgehen müsstest Du dann jede Sekunde den Wert des Timers 
zurücksetzen. Wohl am besten jeweils die Zyklen für eine Sekunde von dem 
aktuellen Wert des Timers abziehen, da ja zwischen der Sekunde und dem 
Laufen der IRQ auch noch Zeit vergeht. Dennoch wirst Du hin und wieder 
eine kleine Differenz haben wenn sich der Timer während dieser 
Berechnung erhöht.

Du musst auch noch einen Randfall bedenken:

was passiert, wenn Dein Event-IRQ getriggert wird, während gerade der 
Erhöhungs-IRQ läuft? Das kannst Du z.B. durch IRQ-Prioriät verhindern.

Wenn Du es noch genauer willst dann nur bei Überlauf den IRQ auslösen. 
Dann musst Du aber noch den Randfall bedenken daß während des Auftreten 
Deines Events der Timer schon übergelaufen ist, aber der Timer-IRQ noch 
nicht laufen konnte.

Und wenn Du sowas mit if-Statements prüfst, dann immer bedenken daß der 
Timer in dem Moment weiterläuft und sich dadurch das Ergebnis im 
Vergleich zu den vorigen ifs verändert haben kann. Das erfordert ein 
bischen sorgfältiges Nachdenken.

von M.A. S. (mse2)


Lesenswert?

lion schrieb:
> Einen Timer-Interrupt der alle µS eine Variable hochzählt
Ich verstehe nur Bahnhof. Wie zählt man mit einem Timer Mikrosiemens?

Jobst M. schrieb:
> 1µS = 1MΩ
Falsch. Richtig ist:
1µS = 1/1MΩ

von Jobst M. (jobstens-de)


Lesenswert?

M.A. S. schrieb:
> Ich verstehe nur Bahnhof. Wie zählt man mit einem Timer Mikrosiemens?

Wenn man schon eine Quelle hat, aus der Microsiemens heraus kommen, kann 
man sie auch zählen.

M.A. S. schrieb:
> Falsch. Richtig ist:
> 1µS = 1/1MΩ

*heul**


Gruß

Jobst

von Axel S. (a-za-z0-9)


Lesenswert?

lion schrieb:
> Also Event A kommt zum Beispiel bei 237µs und Event B kommt
> bei 523µs. Da es aber sehr viele Events gibt und die auch sehr
> sporadisch auftreten können, brauche ich einen Timer der absolut
> arbeitet und konstant hochzählt.

So weit war das schon klar.

> Dafür würde ich natürlich auch einen uint64_t opfern und komme damit bis
> weit weit weit über meine Lebenserwartung hinaus :)
>
> Nichts desto weniger tun mir die 100 kHz IRQ einfach so zu verbraten
> schon ziemlich weh.

Das mit dem Rechnen mußt du noch üben. Für 1µs Zeitauflösung brauchst du 
1MHz, nicht 100kHz. Und natürlich würde man nicht jede µs einen IRQ 
auslösen, um einen µs-Zähler in Software zu inkrementieren.

> So wie ich der Diskussion entnommen habe wäre ein Vorschlag einfach
> einen Timer mit 100 kHz hochzählen zu lassen der dann z.B. alle Sekunde
> (das wäre ok :)) einen IRQ auslöst.

Fast.

Du läßt einfach einen Hardware-Zähler mit 1MHz laufen. In der Breite die 
er eben hat. Wenn das ein 32-Bit Zähler ist, dann läuft er ca. alle 4 
Sekunden über. Für den Überlauf läßt du einen IRQ auslösen und zählst 
die Überläufe in einer zweiten 32-Bit Variable.

> Tritt ein Event auf, nehme ich den aktuellen Zählerstand des Timers +
> den Offset als absoluten Zeitstempel. Haut das so hin?

Wie gesagt: fast. Bei einem Event liest du den Zähler selber und den 
Überlauf-Zähler aus. Zusammen ergeben die einen 64-Bit Zähler mit 1µs 
Zeitauflösung.

Wenn du das dann am Laufen hast, solltest du dir als nächstes die 
Input-Capture-Möglichkeiten der diversen Timer anschauen.

von Jobst M. (jobstens-de)


Lesenswert?

Axel S. schrieb:
> Du läßt einfach einen Hardware-Zähler mit 1MHz laufen. In der Breite die
> er eben hat. Wenn das ein 32-Bit Zähler ist, dann läuft er ca. alle 4
> Sekunden über.

Dann zählt er mit 1GHz.

Nanosiemens waren nicht gefordert. :-D


Gruß

Jobst

von temp (Gast)


Lesenswert?

Ein 32bit Zähler würde also alle 1,19h überlaufen. Wenn du nur eine 
einzige Routine baust die den Zähler ausliest geht sowas (ungetestet):
1
uint32_t tLast=0;
2
uint32_t tOffset=0;
3
4
uint64_t GetTimeStamp()
5
{
6
  uint32_t tAkt=..... // Timer auslesen
7
  if (tAkt<tLast)
8
    {
9
    tOffset++;
10
    tLast=tAkt;
11
    }
12
  return (((uint64_t)tOffset)<<32)+tAkt;
13
}

brauchst du gar keinen Interrupt, wenn sichergestellt ist dass zwischen 
2 Abfragen nicht mehr als 1,19h vergehen.

von Wolfgang (Gast)


Lesenswert?

Jobst M. schrieb:
> Warum so kompliziert?
>
> 1µS = 1MΩ

Das "S" findet jeder hornlose Ochse auf der Tastatur, aber mit dem "Ω" 
tut sich doch mancher schwer.

von Axel S. (a-za-z0-9)


Lesenswert?

Jobst M. schrieb:
> Axel S. schrieb:
>> Du läßt einfach einen Hardware-Zähler mit 1MHz laufen. In der Breite die
>> er eben hat. Wenn das ein 32-Bit Zähler ist, dann läuft er ca. alle 4
>> Sekunden über.
>
> Dann zählt er mit 1GHz.

Ürks. Wie peinlich :O

Wo ich den TE selber erst auf einen Rechenfehler hingewiesen habe

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
Noch kein Account? Hier anmelden.