AVR-Interrupts im Mikrosekundenbereich

Am Mon, 07 Jan 2008 11:13:58 +0100 schrieb Udo Piechottka:

Nein, ich hatte da schon geschaut, aber das zuerst übersehen.

Merkwürdigerweise sieht man in der über den Interruptvektor angesprungenen Routine nur wie die Register am Ende wiederhergestellt werden, deshalb fiel mir das vorn, wo der Zähler neu gesetzt wird, nicht auf. Damit muss ich mich nochmal genauer beschäftigen, das kann ja eigentlich nicht sein. Irgendwas habe ich da noch nicht richtig verstanden.

Lutz

--
Mit unseren Sensoren ist der Administrator informiert, bevor es Probleme im 
Serverraum gibt: preiswerte Monitoring Hard- und Software-kostenloses Plugin 
auch für Nagios - Nachricht per e-mail,SMS und SNMP: http://www.messpc.de
Neu: Ethernetbox jetzt auch im 19 Zoll Gehäuse mit 12 Ports für Sensoren
Reply to
Lutz Schulze
Loading thread data ...

Lutz Schulze schrieb:

Wie wärs wenn du einfach den "Clear Timer on Compare Match (CTC) Mode" verwendest. Damit brauchst du den Timer nicht händisch nachladen und bekommst taktgenaue Aufrufe deiner ISR (die natürlich in

Reply to
Matthias Weisser

Am Mon, 07 Jan 2008 18:04:00 +0100 schrieb Matthias Weisser:

Ja, das wäre eine angemessene Lösung, ich war da auf dem Holzweg.

Ich bin aber mittlerweile von den ganz kurzen Interrupts weg, rufe den Interrupt jetzt alle 100 µsec auf und schiebe die Bits per Software auf den Ausgang. Damit bleiben knapp 50% der Rechenzeit für den Rest drumrum. Das läuft soweit und lässt sich durch Füllbefehle auch recht genau justieren.

Die Erkenntnisse kann man aber bestimmt bei einem der nächsten Projekte brauchen, bisher hatte ich mit den Atmegas nicht so zeitkritische Sachen in Software zu realisieren.

Lutz

--
Mit unseren Sensoren ist der Administrator informiert, bevor es Probleme im 
Serverraum gibt: preiswerte Monitoring Hard- und Software-kostenloses Plugin 
auch für Nagios - Nachricht per e-mail,SMS und SNMP: http://www.messpc.de
Neu: Ethernetbox jetzt auch im 19 Zoll Gehäuse mit 12 Ports für Sensoren
Reply to
Lutz Schulze

Moin,

Michael Baeuerle schrub:

Interessehalber: Wird er Interrupt sofort ausgelöst, wenn er fällig ist, oder wird gegebenenfalls noch darauf gewartet, bis so ein 2-Takte-Befehl fertig ist? Ich würde zweiteres vermuten, allerdings heißt das ja, dass man den Zeitpunkt des Interrupt nur auf 2 Takte genau festlegen kann. Also eine gewisse Unschärfe in der Reaktionszeit hat.

CU Rollo

Reply to
Roland Damm

Und das geht mit output compare? Die meisten CPUs werden ja den aktuellen Befehl erst zuende abarbeiten, bevor der Interrupt ausgelöst wird. Das bedeutet dann, daß bei Befehlen, die 2 Taktzyklen dauern, der Interrupt mit

1 Taktzyklus Jitter ausgelöst wird. Dies muß man dann, bei hohen Anforderungen an den Jitter, per Software ausgleichen.
--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Reply to
Frank Buss

uf den

u

Apropos justieren: wenn man eine Datenquelle hat, die mit jedem Prozessortakt eins hochz=E4hlt, dann kann man auch den Beginn der ISR auf=

einen Takt genau legen. Wurde fr=FCher beim C64 gemacht f=FCr vertikale Raster (Umschaltung von Farbregistern mitten in der Videozeile). Interrupt kam am Anfang der Videozeile mit variabler Latenz, dann wurde per Software auf einen Taktzyklus genau angeglichen.

Sinnvoller ist es allerdings, das mit output compare von der Hardware erledigen zu lassen.

XL

Reply to
Axel Schwenke

Moin!

Nein.

Ja.

Eben deshalb - Du weißt nie, ob der Controller binnen 1 oder 2 Takten seinen altuellen Befehl abgearbeitet hat und in den Interrupt springt.

Gruß, Michael.

Reply to
Michael Eggert

Es ist sogar noch schlimmer. Es gibt Befehle die mehr als

2 Takte brauchen. RCALL (3 oder 4) und RETI (4 oder 5) z.B.

Gerrit

Reply to
Gerrit Heitsch

Alle Befehle sind "atomic", laufen also immer zu Ende. D.h. beim ATmega8 muss man im worst case mit 4+4 Takten rechnen (der hat keinen Befehl der

5 Takte benoetigt). Aus dem Standby sind es 10+4 Takte wenn ich das richtig verstehe (6 zum Aufwachen plus 4 zusaetzliche Takte Interruptlatenz, der SLEEP Befehl ist per Definition komplett ausgefuehrt).

Micha

Reply to
Michael Baeuerle

Genau so ist es, nur der Mittelwert stimmt.

Das Problem hat man ggf. genauso bei nichtperiodischen Interrupts.

Ich habe das schonmal taktgenau gebraucht und so geloest, dass ein zweiter Interrupt rechtzeitig vorher getriggert wurde. Dessen ISR hat dann den Weg bereitet: Alle restlichen Interrupts maskiert, das I-Flag gesetzt und anschliessend soviele NOPs ausgefuehrt, dass auch im worst case der eigentliche Timerinterrupt immer nach einem NOP unterbrochen hat. Je nach Intervall und Prescaler kann das aber eine ziemliche Verschwendung von Rechenpower und Programmspeicher nach sich ziehen (ein manuell abzubrechender NOP-Loop ist keine Loesung, weil es keinen Sprungbefehl gibt der nur einen Takt benoetigt).

Micha

Reply to
Michael Baeuerle

e

Mi=DFverst=E4ndnis. Ich meinte, wenn man eine taktgenaue Reaktion an eine= m Pin braucht, macht man das besser per OC. F=FCr die Angleichung im Software w=FCrde man einfach den Timer auslesen und abh=E4ngig davon, wie=

weit man entfernt ist, mehr oder weniger NOPs =FCberspringen, bevor man a= n die richtige Arbeit geht.

XL

Reply to
Axel Schwenke

Vergiss nicht, dass ein IRQ nur den PC mit dem Vektor laedt. Dort wartet im Normalfall ein RJMP der auch noch 2 Zyklen sehen will. Erst dann kannst du mit deiner IRQ-Routine loslegen.

Gerrit

Reply to
Gerrit Heitsch

Der RJMP aus der Vektortabelle ist dann aber immer da und erzeugt kein Jitter, dessen Laufzeit kann man also normalerweise fest ins Timing mit einrechnen. Man hat dann eine feste Interruptlatenz von 6Takten (plus

1Takt unvermeidliches Jitter bei asynchronen Interrupts). Man kann auch auf 4Takte runterkommen wenn man alle anderen Interrupts deren Vektoren auf hoeheren Adressen liegen maskiert, den RJMP weglaesst und die ISR einfach an der Vektoradresse beginnen laesst.

Micha

--
http://micha.freeshell.org/
Reply to
Michael Baeuerle

Nette Idee, aber nach Murphy funktioniert das nicht weil du einen der nachfolgenden IRQs brauchst. :)

Gerrit

Reply to
Gerrit Heitsch

Moin,

Gerrit Heitsch schrub:

Interessant. Habe bisher nur mal einen Grundkurs in ...(irgendwas mit '85 hieß der Prozessor) in Assembler gehabt. Zu solchen Tiefsinnigkeiten kam der Kurs nicht (obwohl er verräterischerweise 'Echtzeitprogrammierung' hieß).

CU Rollo

Reply to
Roland Damm

Ja Murphy, aber auch der ist nicht unfehlbar. Man kann ihn ggf. ueberlisten, indem man die "Inline-ISR" so optimiert, dass sie noch vor dem Ende der Vektortabelle zu Ende ist ;-)

Bei den grossen AVRs ist die Tabelle immerhin 232Bytes gross ... so kann man z.B. bei einem ATmega640 wohl oft die USART Vektoren "retten" die ganz am Ende der Tabelle liegen.

Micha

Reply to
Michael Baeuerle

Hier stehen ja schon ueber 30 Tips, deshalb auf die Gefahr hin dass es schon gesagt wurde:

  1. Die Interrupt Reaktionszeit haengt davon ab, welche Befehle gerade ausgefuehrt werden. Beispielsweise braucht ein "nop" weniger Zeit als ein Sprungbefehl. Somit tritt der Interrupt nicht immer exakt zum gewuenschten Zeitpunkt auf.
  2. Du solltest die "Auto-Reload" Funktion benutzen, damit der Timer nicht aus dem Tritt kommen kann. Dh der Interrupt loest zwar evt mit kurzen Verspaetungen aus, diese summieren sich aber nicht zu einer immer groesseren Verspaetung auf.
  3. Falls auch kurze Verspaetungen ein Problem darstellen, solltest Du vor dem setzen des IO Pins (in der Interrupt-Funktion) eine Korrektur- Pause einlegen. Dazu liest Du am besten den Timer (der dank Auto- Reload schon wieder am Zaehlen ist), rechnest die Differenz zu einem Soll-Zeitpunkt aus, und springst per berechnetem Sprung ("ijmp" Befehl) in eine Reihe von "nop" Befehlen. Je "frueher" der Interrupt ausgeloest wurde, desto mehr "nop"s fuehrst Du aus, und je "spaeter" der Interrupt, desto weniger. Somit korrigierst Du die Verspaetung, die nach dem letzten "nop" immer exakt dieselbe ist. Jetzt kannst Du den IO Pin 100% im Takt aktualisieren.

Gruesse, Marc

Reply to
Marc Jet

Wahrscheinlich wurde die Lektuere der Befehlsreferenz und des Datenblattes der entsprechenden CPU stillschweigend vorausgesetzt. :)

Sollte man auch als C-Programmierer einen Blick reinwerfen.

Gerrit

Reply to
Gerrit Heitsch

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.