Timer als Zeitbasis

wer

Neues Mitglied
02. Juli 2012
485
0
0
Sprachen
  1. Assembler
Hallo,

ich suche eine optimale Lösung für die folgende Situation:

ATmega1284p, 19660800Hz

Ich möchte verschiedene Zeiten (Timeouts, Delays) warten können, ohne den MC nur Däumchen drehen zu lassen.
Meine Zeiten möchte ich in ms angeben können.

Dazu dachte ich mir zunächst das folgende:
Ich reserviere eine ausreichende Anzahl Register, z.B. R2, R3, R4 als Timerflags
Ich setze eines meiner Register (z.B. ldi R2,40)
In einer ISR, die jede ms aufgerufen wird, dekrementiere ich R2, R3, R4 solange sie größer als 0 sind.
In meiner Hauptschleife teste ich R2 auf 0 und kann dann (40ms später) reagieren.

Dieser erste Entwurf gefällt mir aus verschiedenen Gründen nicht. Vielleicht kann mir jemand helfen ihn zu verbessern.

Meine Einwände:
  • Zu dem Zeitpunkt, zu dem ich R2 setze, kann der nächste Interrupt kurz bevorstehen oder gerade eben verstrichen sein.
    D.h. ich habe einen maximalen Fehler von 1ms (im Mittel 0,5ms). Natürlich könnte ich meine Zeitbasis verkleinern, aber damit
    zwacke ich dem MC zusätzliche Rechenzeit für die ISR ab.
  • Ich finde keine CTC / Prescaler Werte für glatte ms, 1/10ms, 1/100ms Werte
  • Ich will nicht unbedingt all zu viele Register für diesen Zweck reservieren

Wolfgang
 
Was'n das für'n komischer krummer Quarz? Und wofür?

Mal direkt zu Punkt 2:
Wie stellst Du Dir das auch vor? Geh es doch mal mit reiner Mathematik an...
Der Controller hat keine interne PLL, oder?
Dein Prozessor macht 19660800 Takte pro Sekunde. Eine Millisekunde entspricht also exakt 19660,8 Takten, 100µs exakt 1966,08 Takten und 10µs exakt 196,608 Takten. Wenn Du den Wert ohne Vorteiler nicht treffen kannst, kannst Du es mit Vorteiler erst recht nicht.
Den kleinsten"runden (dezimalen) Sekundenanteil", den Du treffen kannst ist 'ne Centisekunde. Das wären 196608,00 Takte.

Zu den anderen beiden Punkten:
Wenn Du nun mehrere verschiedene Zeitbasen aus einem Timer generieren willst, mußt die Basis des Timers ein gemeinsamerTeiler von den Zeitbasen sein. Der größte gemeinsame Teiler liefert Dir dann die langsamste Zeitbasis, die alle Basen trifft.
Ob Du nun generell alle Deine Berechnereien/Zählereien in diese eine Zeitbasis überträgst, oder Dir mehrere Zählregister dafür generierst, mußt Du dann halt selbst entscheiden
 
Wenn Du nun mehrere verschiedene Zeitbasen aus einem Timer generieren willst, ...

Ich will nicht mehrere verschiedene Zeitbasen, sondern eine. Ist das nicht klar geworden?

Mich interessiert, wie Ihr sowas angeht und wie Ihr die angesprochenen Probleme löst.

Wolfgang
 
Hmm...
Ansichtssache:
...Ich möchte verschiedene Zeiten (Timeouts, Delays) warten können...
kann man ja auch als Zeitbasis interpretieren...
Timeout A soll mit einer festgelegten Periodendauer (t(A)) generiert werden, Delay B mit einer anderen Periodendauer (t(B)). Eventuell hast Du noch weitere Anforderungen (t(C), t(D),...), "Zeitbasen"...
Wenn Du die alle mit einem Timer, mit einer Zeitbasis treffen willst, muß die effektive Periodendauer logischerweise ein irgendein gemeinsamer Teiler aller "Periodendauern"(?) der vorgegebenen "Zeitbasen" (A, B, ...) sein.
Je kleiner dieser gemeinsame Teiler (die effektive Periodendauer/Deine letztendliche Zeitbasis ist), desto höher löst der Timer in Deinen Anforderungen noch auf (also ggf noch feiner als Du mit Deinen Delays etc eigentlich forderst), aber dadurch sinkt logischerweise auch die Reichweite des Timers.
Der größte gemeinsame Teiler liefert dann genau die längste Periodendauer, die alle Anforderungen trifft, also die langsamst-mögliche Einstellung für den Timer (und somit die größte Reichweite).

Genau das hatte ich ja bereits geschrieben.

Nochmal zum Quarz: das scheint ein spezieller Baudratenquarz zu sein, der quasi die 4800er Reihe (Verdopplungen) trifft, aber eben nicht alle üblichen (anderen) Baudraten, insbesondere scheinen 115200baud (und 230400baud) nicht mehr machbar (da die nicht auf dieser Reihe liegen), was ein "echter" Baudratenquarz (zB 1,8432MHz) kann (dieser allerdings bei den 230,4kbaud nur noch mit 8fach Oversampling).
Mit Deinem Quarz sollte (auf dieser Reihe) 1.882.200baud das Maximum sein (16fach-Oversampling), bzw 2.457.600baud mit 8fach-Oversampling(wenn ich mich nicht verrechnet habe).
Also ohne prozentualem rechnerischen Fehler.
Wer diese Rate entgegennimmt, ist jetzt 'ne andere Frage.
Ebenso erreicht ein 20MHz Quarz etwas schnellere Baudraten - nur eben nicht die"üblichen"
 
Hmm...
Ansichtssache:

kann man ja auch als Zeitbasis interpretieren...
Timeout A soll mit einer festgelegten Periodendauer (t(A)) generiert werden, Delay B mit einer anderen Periodendauer (t(B)). Eventuell hast Du noch weitere Anforderungen (t(C), t(D),...), "Zeitbasen"...
Wenn Du die alle mit einem Timer, mit einer Zeitbasis treffen willst, muß die effektive Periodendauer logischerweise ein irgendein gemeinsamer Teiler aller "Periodendauern"(?) der vorgegebenen "Zeitbasen" (A, B, ...) sein.
Je kleiner dieser gemeinsame Teiler (die effektive Periodendauer/Deine letztendliche Zeitbasis ist), desto höher löst der Timer in Deinen Anforderungen noch auf (also ggf noch feiner als Du mit Deinen Delays etc eigentlich forderst), aber dadurch sinkt logischerweise auch die Reichweite des Timers.
Der größte gemeinsame Teiler liefert dann genau die längste Periodendauer, die alle Anforderungen trifft, also die langsamst-mögliche Einstellung für den Timer (und somit die größte Reichweite).

Genau das hatte ich ja bereits geschrieben.
Hier noch einmal ein Beispiel, da das ja irgendwie nicht klar wird.

Meine Zeitbasis könnte z.B. die Millisekunde sein. Dann möchte ich diverse Zeiten unabhängig voneinander warten können, deren Zeitdauern alle in Millisekunden angegeben werden. Ich setze also z.B. R2 auf 40, weil ich an einer Stelle 40ms warten will und R3 auf 130ms, weil ich an einer anderen Stelle einen Timeout von 130ms benötige, usw.
 
Ich kenne mich mit ASM nicht aus. Kann man dort Parameter an einer Funktion übergeben?
Wenn ja wieso machst du es nicht einfach wie beschrieben...

Einen Timer der eine Variable bei jedem Tick hochzählt und diese pollst du einfach? Wäre das nen machbarer Weg?
 
Ich kenne mich mit ASM nicht aus. Kann man dort Parameter an einer Funktion übergeben?
Wenn ja wieso machst du es nicht einfach wie beschrieben...
Assembler ist keine Hochsprache hier gibt es erst mal nur Instruktionen keine Funktionen und keine Routinen. Diese schreibt man sich erst und die Parameterübergabe definiert man selber, entweder über Register oder SRAM. Es ist aber eigentlich auch egal, man bekommt das auch mit Assembler hin ;)
Einen Timer der eine Variable bei jedem Tick hochzählt und diese pollst du einfach? Wäre das nen machbarer Weg?
Wenn das Hauptprogramm zu sehr "belastet" ist, verpasst du ggf. einen Wert. Besser ist, wenn die TimerISR einmalig ein Flag setzt, welches das Hauptprogramm pollt und es selber wieder zurücksetzt.

Das Thema ist ja schon recht alt und eventuell schon längst gelöst.
 
Zuletzt bearbeitet:
Um's mal auf'n Punkt zu bringen:
In Assembler gibt's für jede Maschinencode-Instruktion einen Assembler-Mnemonic. (für manche sogar mehrere, aber die haben dann dieselbe Funktion, sind quasi identisch). Das wars.
Du kannst also Rechenregisterinhalte addieren, subtrahieren, bei Megas auch multilizieren, inkrementieren und dekrementieren, links- oder rechtsschieben/rollen und sie bitweise logisch verknüpfen. Miteinander, und teilweise auch mit Konstanten.
Das wars mit den "Rechenoperationen".
Dann kannst Du Bytes zwischen den Rechenregistern hin und herkopieren, oder zwischen Rechenregistern und SRAM (Spezialfall -> I/O-Register). Der Zugriff auf internen Eeprom und Flash läuft über I/O-Register).
Und dann gibt es noch Sprünge, generelle, oder welche, die an irgendwelche Bedingungen geknüpft sind. Welche die ein Konstant festgelegtes Ziel haben, oder welche, wo das Ziel zur Laufzeit variieren kann.

Du hast in Assembler immer Zugriff auf jedes Bit.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)