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
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.
@ 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. ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.