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
1 | Timer ------|----------|----------|----------|----------|---- |
2 | Software Uhr ------1----------2--------------3------4----------5---- |
3 | xy-IRQ ---------------------------AKTIV----------------------- |
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.
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.