Hallo Forum
Folgende Situation:
Ich habe hier eine Schaltung, welche einen Schrittmotor ansteuert. Der
Schrittmotor ist pro Tag ca. 2-3 mal im Einsatz, immer für rund 10
Minuten. Genau diese Betriebszeit von rund 30 Minuten täglich soll
gemessen werden.
Für die Speicherung der Betriebszeit habe ich an ein EEPROM gedacht, das
dürfte ja nicht all zu schwer sein.
Was mir im moment eher den Kopf zerbricht, bzw. wobei ich nicht ganz
sicher bin ich die Erzeugung einer "Referenz"zeit.
Mein uC wird mit einem externen Quarz betrieben, 40 MHz. Denke nicht
dass es sonderlich schlau wäre, die Zeit direkt aus dem uC berechnen zu
lassen. (Oder vielleicht doch?)
Gibt es irgendwelche Standards wie sowas gemacht wird?
Vielen dank für die Hilfe
Helper schrieb:> Mein uC wird mit einem externen Quarz betrieben, 40 MHz. Denke nicht> dass es sonderlich schlau wäre, die Zeit direkt aus dem uC berechnen zu> lassen.
Warum nicht?
Auf wiviele Mykrosekunden (millionstel Sekunden) genau musst du denn die
Zeit kennen?
Mit einem Quarz bist du recht einfach bei weniger als 100 ppm (parts per
million). Ob dein Quarz also tatsächlich 40 Millionen Schwingungen pro
Sekunde macht oder ob es doch 40 Millionen und 56 sind, kann man also
ohne nachzumessen nicht so genau sagen.
Aber summier dir das doch mal auf, wie lange es bei deinen Daten dauert
(30 Minuten am Tag), bis sich dieser Fehler im schlimmsten Fall auf 1
Sekunde addiert.
Wenn der Quarz arg daneben ist (kommt vor), dann kann man auch noch ein
paar Tagen die tatsächliche Quarzfrequenz aus der Abweichung
zurückrechnen und im Programm berücksichtigen.
Oder brauchst du die Zeit Atomuhr-genau auf tausendstel Nanosekunden
genau?
Werde das mal durchrechnen...
Wie würde man das rein Software technisch am saubersten lösen? Vermute
mal Timer wäre da die schlauste Variante oder?
Wie sieht es dann aus, wenn der uC regelmässig ein UART Interrupt
aufgelösst bekommt? Stellt das irgendwelche Probleme bezüglich der
Interrupts für den Timer? Dürfte bei den neueren uC's alles lösbar sein
mit diesen Interrupt Prioritätslevel oder?
Rechnen wir mal:
30 Min Messdauer pro Tag = 1800 Sekunden.
Fehler des 100ppm-Quarzes = 1800s *100 / 1.000.000 = 180ms.
Macht also ca 1s Fehler in 5-6 Tagen.
Falls du damit nicht leben kannst, nimm einfach einen besseren Quarz
oder Quarzoszilator.
Helper schrieb:> Werde das mal durchrechnen...>> Wie würde man das rein Software technisch am saubersten lösen? Vermute> mal Timer wäre da die schlauste Variante oder?
Natürlich.
Sobald in einer Aufgabenstellung das Wort 'Zeit' vorkommt, kann man
seinen Allerwertesten darauf verwetten, dass der vernünftigste
Lösungsweg über einen Timer führt.
> Wie sieht es dann aus, wenn der uC regelmässig ein UART Interrupt> aufgelösst bekommt? Stellt das irgendwelche Probleme bezüglich der> Interrupts für den Timer?
Deine UART legt ja nicht den µC für Stunden lahm. Dann kommt ein Timer
Interrupt halt mal ein paar µs zu spät. Was aber nichts macht, denn der
nächste kommt unabhängig davon dann wieder zum richtigen akkumulativen
Zeitpunkt. D.h. deine Uhr 'hinkt' vielleicht kurzfristig um deine
kleinste Zeiteinheit mal nach, holt das aber gleich darauf wieder auf.
Ist deine kleinste Zeiteinheit eine Tausendstel Sekunde (für einen µC
immer noch eine halbe Ewigkeit), dann ist die akkumulierte Zeit
vielleicht mal etwas hinten, mit dem nächsten Timer Tick stimmt aber
alles wieder, weil ja der Timer unabhängig vor sich hin tickt.
Es ist im Grunde wie eine Uhr die an der Wand hängt und die nur einen
Sekundenzeiger hat (wodurch die regelmässig hinsehen musst um keine
Minute zu verpassen). Nur weil du mal kurz keine Zeit hast aufs
Zifferblatt zu sehen, verlierst du ja deswegen keine Zeit. Die Uhr läuft
ja trotzdem unabhängig davon weiter, egal ob du Zeit hast aufs
Zifferblatt zu sehen oder nicht. Erwischt du die Uhr nicht exakt im
Zeitpunkt an dem der Sekundenzeiger auf 0 steht, dann erwischt du ihn
eben bei 5 Sekunden das nächste mal. Deine Minuten hinken dann diese 5
Sekunden lang hinten nach. Aber den nächsten 0-Durchgang kriegst du
wieder zeitgerecht mit, so dass in Summe deine Minutenzählerei stimmt.
Problematisch wird es erst, wenn du tatsächlich mal keine ganze Minute
Zeit hast, auf die Uhr zu sehen und du 2 0-Durchgänge hintereinander
verpasst. Aber diesen Fall hast du ja in einem µC nicht bzw. den kann
man ganz leicht vermeiden. Unter anderem auch deshalb, weil die Dinger
(die µC) eben so sauschnell sind, dass sie ~30 Millionen Instruktionen
pro Sekunde abarbeiten können. Das holen eines Bytes von der UART und
die Verarbeitung davon dauern vielleicht 100 bis 200 Takte. Damit bleibt
ein erkleklicher Anteil an Instruktionen pro Sekunde übrig, selbst wenn
die andere Seite der UART eine richtige QUasselstrippe ist.
Was Karl Heinz sagt, ist absolut richtig!!!
Wenn du dennoch eine sehr genaue Zeit angabe brauchst kannst du eine RTC
nehemn gibt es bis genauigkeiten <10ppm. Unterscheidet sich jedoch nicht
sehr von einem guten Quarz. Vorteil du kannst gleichzeitig abspeichern
wann (Datum Uhrzeit...) der Schrittmotor gelaufen ist. Weiterer Vorteil,
ist unabhängig von Quarz und dementsprechend kann die genauigkeit der
Zeit bei größeren Stückzahlen aus dem Design heruas garantiert werden.
Nachteil: Zusätzliches IC, Stromverbrauch, Platzverbrauch...
Hast du zugang zum Internet???
Dann würde ich es mittels SNTP lösen.
Schlumpf schrieb:> Macht also ca 1s Fehler in 5-6 Tagen.>> Falls du damit nicht leben kannst, nimm einfach einen besseren Quarz> oder Quarzoszilator.
Ich denke, damit komme ich gaaanz knapp klar. :P
Ne im ernst, reicht locker. Vielen dank für die Rechnung. :)
Karl Heinz schrieb:> Natürlich.> Sobald in einer Aufgabenstellung das Wort 'Zeit' vorkommt, kann man> seinen Allerwertesten darauf verwetten, dass der vernünftigste> Lösungsweg über einen Timer führt.
Sehr gut, dann lag ich da ja schonmal richtig.
Karl Heinz schrieb:> Dann kommt ein Timer> Interrupt halt mal ein paar µs zu spät
Okay. Verstehe ich das also richtig:
Wenn der uC gerade die Interrupt Routine für den UART abarbeitet und
während dem ein Timerinterrupt auftritt, dann wird der Timerinterrupt
direkt nach dem UART Interrupt ausgeführt, der Wert des Timers
allerdings unabhängig von der abarbeitung der ISR bereits wieder weiter
zählt?
Würde also heissen wenn z.B. jede Sekunde der Imter überläuft spielt es
keine Rolle wann in der darauffolgenden Sekunde der Interrupt ausgelösst
wird, der Timer zählt automatisch jede Sekunde wieder von 0?
Oder meintest du damit nur, dass die Abarbeitung der UART ISR so schnell
sein sollte, dass es nicht ins Gewicht fällt?
(Spielt für meine Anwendung eigentlich keine Rolle mehr, meine UART ISR
ist bestimmt kurz genug, ist gerade eher generelles Interesse).
Philipp schrieb:> Nachteil: Zusätzliches IC, Stromverbrauch, Platzverbrauch...> Hast du zugang zum Internet???> Dann würde ich es mittels SNTP lösen.
Platz, Stromverbrauch undsoweiter sind absolut kein Problem. Das ganze
soll nicht in Serie Produziert werden sondern dient als einmaliges
Projekt. Von demher stören da paar mA nicht. ;)
Zugang zum Internet wäre vorhanden, überschreitet dann allerdings
langsam mein Wissen. Müsste ich mich mal einlesen und schauen wie
kompliziert das ganze ist, denke aber ich bleibe bei der Variante mit
dem uC.
Helper schrieb:> Okay. Verstehe ich das also richtig:> Wenn der uC gerade die Interrupt Routine für den UART abarbeitet und> während dem ein Timerinterrupt auftritt, dann wird der Timerinterrupt> direkt nach dem UART Interrupt ausgeführt, der Wert des Timers> allerdings unabhängig von der abarbeitung der ISR bereits wieder weiter> zählt?
Exakt.
> Würde also heissen wenn z.B. jede Sekunde der Imter überläuft spielt es> keine Rolle wann in der darauffolgenden Sekunde der Interrupt ausgelösst> wird, der Timer zählt automatisch jede Sekunde wieder von 0?
Genau
> Oder meintest du damit nur, dass die Abarbeitung der UART ISR so schnell> sein sollte, dass es nicht ins Gewicht fällt?
Ich weiß nicht, welche Vorstellungen du davon hast, wie lange so etwas
dauert. Was macht man denn in einer UART-ISR? Man holt sich das Zeichen,
macht vielleicht noch ein paar kurze Chzecks auf Gültigkeit, speichert
das empfangene Zeichen vielleicht noch in einem Buffer, tja. das wars
dann aber auch schon. Recht viel mehr als 10 bis 20µs gehen da auf
keinen Fall drauf. Und da hab ich bei 40Mhz schon großzügig geschätzt.
Im Vergleich zu der einen kompletten Sekunde (die du angenommen hast)
also praktisch nichts. Und nach dieser Zeit sind die Interrupts wieder
freigegeben, so dass der 1 Timer-Interrupt der zwischenzeitlich
möglicherweise angefallen ist, jetzt (mit 20µs Verspätung) nachgeholt
wird. Der Timer ist zwischendurch ja sowieso weiter gelaufen, so dass
auf lange Sicht nichts verloren gegangen ist.
Karl Heinz schrieb:> Deine UART legt ja nicht den µC für Stunden lahm. Dann kommt ein Timer> Interrupt halt mal ein paar µs zu spät.
... was natürlich voraussetzt, dass die UART-Interruptroutine
'ordentlich' geschrieben ist (d.h. ohne Warteschleifen) und der Timer
ebenso 'ordentlich' arbeitet (d.h. der Timer hardwaremäßig frei läuft
ohne Laden oder Resetten in der Interruptroutine).
Gruß Dietrich
Eine ISR sollte prinzipiell so geschrieben werden, dass sie
schnellstmöglich wieder verlassen wird. In jedem System unabhängig von
den Anforderungen. Alles andere ist in meinen Augen ein unsauberer
Programmierstiel
Den Timer machst du als rundlaufenden Timer. Das heißt, es ist dann
nichts anderes, als ein Hardware-Zähler im Prozessor, dem es völlig
schnuppe ist, was deine Software gerade macht. Der Zähle einfach immer
von einem Startwert bis 0x00 runter, löst einen Interrupt aus und fängt
wieder von vorne an.
Ist deine SW gerade mit einem andern IRQ beschäftigt, so kann z.B. der
Timer-Interrupt direkt im Anschluss an den anderen IRQ bearbeitet
werden.
Zeitlich sieht das dann so aus
Vielen lieben Dank für all die super schnellen und tollen Antworten!
Das mit dem ISR programmieren ist mir bekannt, dafür sorge ich schon
dass der Code so klein wie möglich sein wird.
Vielen dank analle!
Helper schrieb:> Vielen lieben Dank für all die super schnellen und tollen Antworten!>> Das mit dem ISR programmieren ist mir bekannt, dafür sorge ich schon> dass der Code so klein wie möglich sein wird.
Ja, aber Achtung:
so klein wie möglich bedeutet nicht, das man gar nichts machen darf.
zb wird man das hochzählen einer Uhr (Hundertstel, Sekunden, Minuten,
Stunden) zur Gänze in der ISR machen und sich nicht nur 1 Flag setzen
und das Hochzählen der Hauptschleife überlassen. So eine Uhr betrachtet
man als 1 Einheit die als Einheit hochgezählt wird und nur aus
technischen Gründen in Sekunden und Minuten zerfällt.