Forum: Compiler & IDEs Interrupt Event während Interrupt


von Thomas U. (morrie)


Lesenswert?

Hallo Leute,
ich programmiere gerade eine Schrittmotorsteuerung und komme an einen 
Punkt, an dem ich nicht ganz genau verstehe wass passiert wenn 2 
Interrupts aufeinander treffen (Ich verwende den Atmega32).
Die Schrittmotorsteuerung soll sehr genau laufen, deshalb verwende ich 
einen Schrittmotor mit externem Geber und lasse einen PID drauf laufen.

Dafür muss ich ein hochgenaues Sollsignal generieren. Für dieses 
Sollsignal verwende ich ein Timer Interrupt des MCs alle 10,24ms. D.h. 
alle 10,24 ms wird auf das Sollsignal ein definierter Wert addiert.

Jetzt verwende ich für die Schrittmotorsteuerung einen zweiten Timer, 
der mir die Schritte generiert.

Jetzt meine konkreten Fragen:

1. Für die Generierung des Sollsignals werden nur volle Timerüberläufe 
verwendet. Der Timer wird also während des Interrupts nicht neu 
initialisiert. Ist es richtig, dass der Timer dann alle 10,24ms 
aufgerufen wird, oder wird der Timer nach Ende des Interupts erst wieder 
gestartet. Dann würde mein Interrupt ja nicht alle 10,24ms sondern alle 
10,24ms plus die Laufzeit des Codes im Interrupt ausgelöst.

2. Der Jitter des Timer Interrupts kann ja ein paar Zyklen des MCs 
betragen, da der letzte Befehl des Codes ja abgearbeitet werden muss 
bevor der Interrupt gestartet werden kann (Ret dauert z.B 4 Zyklen). 
Läuft während dieser Zeit mein Timer im Hintergrund weiter, oder dauert 
meiner nächstes Timer Event dann 10,24ms + 0-4 Zyklen des MCs?

3. Wass passiert wenn ich mich gerade in dem Interrupt des anderen 
Timers befinde, der die Schritte für den Schrittmotor auslöst und dann 
mein Timerinterrupt für das Sollsignal ausgelöst wird. Geht der dann 
verloren, wird der hinten angestellt, oder kann ich aus einem Interrupt 
in einen anderen sprigen?

Ich hoffe ich konnte meine Probleme klar formulieren.

Danke schon mal für die Anworten.

Thomas

von Bronco (Gast)


Lesenswert?

Der Timer ist ein Hardware-Register, das mit einer festen Frequenz hoch 
oder runter zählt. Solange Du keine Manipulation (wie Überschreiben des 
Registers) vornimmst, läuft er völlig autark und unabhängig von Deiner 
Software.
Bei einem bestimmten Event (z.B. Überlauf) wird das InterruptRequestFlag 
(IRQ) gesetzt. Auch das passiert in Hardware und somit ohne Verzögerung.
Wenn das entsprechende InterruptEnableFlag (IEN) gesetzt ist und die 
Interrupts global freigegeben sind, wird die ISR nach Vollendung des 
aktuellen Maschinenbefehls angesprungen.
Das Anspringen der ISR folgt einem bestimmten Protokoll (siehe 
Datenblatt), weil Rücksprungadresse, Status-Register u.ä. gesichert 
werden müssen. Du hast also immer eine feste Verzögerung von x Takten 
zwischen IRQ und erstem Befehl in der ISR.
Beim AVR ist es so, daß innerhalb einer ISR i.a.R. die Interrupts global 
gesperrt sind. Wenn während der Abarbeitung einer ISR das IRQ einer 
anderen ISR gesetzt wird, so wird die zweite nach Beendiung der ersten 
abgearbeitet. Du kannst natürlich in der ISR die globalen Interrupts 
wieder freigeben, was aber mit Vorsicht zu behandeln ist.
Andere µCs haben Interrupt-Prioritäten, wodurch geregelt ist, welche ISR 
durch welche ISR unterbrochen werden kann.

Übrigens:
Wenn Dein AVR mit 1MHz getaktet ist, hättest Du bei 4 Takten einen 
Jitter von 4µs. Das 0,04% Deiner 10,24ms. Vergleich das mal mit den 
Toleranzen Deines Quarzes.

von Falk B. (falk)


Lesenswert?

@  Thomas U. (morrie)

>Dafür muss ich ein hochgenaues Sollsignal generieren.

Für wen? Den Geber?

> Für dieses
>Sollsignal verwende ich ein Timer Interrupt des MCs alle 10,24ms. D.h.
>alle 10,24 ms wird auf das Sollsignal ein definierter Wert addiert.

Also für die Steuerung.

>Jetzt verwende ich für die Schrittmotorsteuerung einen zweiten Timer,
>der mir die Schritte generiert.

Hmm.

>verwendet. Der Timer wird also während des Interrupts nicht neu
>initialisiert.

Sinnvoll.

>Ist es richtig, dass der Timer dann alle 10,24ms
>aufgerufen wird,

Ja.

> oder wird der Timer nach Ende des Interupts erst wieder
>gestartet.

Nein, er läuft vollkommen parallel zur CPU. Das ist ja der Witz dabei.

> Dann würde mein Interrupt ja nicht alle 10,24ms sondern alle
>10,24ms plus die Laufzeit des Codes im Interrupt ausgelöst.

Eben.

>2. Der Jitter des Timer Interrupts kann ja ein paar Zyklen des MCs
>betragen, da der letzte Befehl des Codes ja abgearbeitet werden muss
>bevor der Interrupt gestartet werden kann (Ret dauert z.B 4 Zyklen).

Jo.

>Läuft während dieser Zeit mein Timer im Hintergrund weiter,

Sicher.

>oder dauert
>meiner nächstes Timer Event dann 10,24ms + 0-4 Zyklen des MCs?

Nein. Die Frequenz ist konstant, aber die Zeitpunkt des Starts des 
Interrupts zittern, aka Jitter.

Siehe Interrupt.

>3. Wass passiert wenn ich mich gerade in dem Interrupt des anderen
>Timers befinde, der die Schritte für den Schrittmotor auslöst und dann
>mein Timerinterrupt für das Sollsignal ausgelöst wird. Geht der dann
>verloren,

Nein.

> wird der hinten angestellt,

Ja.

> oder kann ich aus einem Interrupt
>in einen anderen sprigen?

Kommt auf den Prozessor an. Siehe Interrupt.

>Ich hoffe ich konnte meine Probleme klar formulieren.

Ja. ;-)

von Thomas U. (morrie)


Lesenswert?

Vielen Dank für die schnellen Anworten.
Als Quarz verwende ich ein +-10ppm Quarz.
Der Jitter im Code stört mich auch nicht sonderlich. Der ist wirklich so 
klein, dass er kaum auffält.
Wichtig war mir nur, dass ich nicht jedes Mal einen kleinen Offset von 
ein paar Takten auf meinen Timer bekomme, die sich dann über die Zeit 
aufsummieren.

Aber dann habe ich verstanden wie es funktioniert.

Danke.

Thomas

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.