Hallo, mir ist aufgefallen das derselbe Interrupt unterschiedliche Zeiten benötigt um ausgeführt zu werden. Kann man das verhindern oder irgendwie ausgleichen das immer die exakt selbe oder längste "Sprungzeit" bis zur Ausführung eingehalten wird?
Kommt darauf an, welcher Interrupt ausgeglichen werden soll. Beim Timer kann ich zum Beispiel den Count aulesen und damit die Verspätung ausrechnen und ausgleichen (Timer ohne Vorteiler!). Für einen externen Interrupt müßte ich das ICR laden und ebtsprechend berechnen. Gruß, Klaus
Sorry ATMega16 und Timer1 Der Timer ist so eingestellt: ldi tempL, (1<<CS12)|(1<<CS11)|(0<<CS10)|(0<<WGM12) .... an Port B1 liegt ein externer Takt der den Interrupt nach Übereinstimmung auslöst.
Läubi Mail@laeubi.de wrote:
> [...] Was ist unterschiedlich lange?
Also, definiere "unterschiedliche Zeiten"! Ein bis zwei CPU-Takte
Unterschied können grundsätzlich auftreten und das lässt sich auch nicht
vermeiden, da immer erst der gerade laufende Befehl zuende abgearbeitet
wird. Kollisionen mit anderen Interrupts führen u.U. auch zu verzögerter
Ausführung und zu anderen Problemen. Ohne Dein Programm zu kennen, kann
man da nur mutmaßen.
Hallo, lach jetzt nicht aber es sind ca. 1-3 Prozessortakte auch im AVR Studio zu sehen. Für meine Anwendung ist es wichtig das immer die selbe Zeit eingehalten wird mit 10 Takten kann ich auch leben nur müssen die exakt gleich lang sein. Bitte stellt das jetzt nicht in Frage es ist einfach so.
René Schink wrote: > lach jetzt nicht aber es sind ca. 1-3 Prozessortakte auch im AVR Studio > zu sehen. Siehe oben! Lachen tu ich sicher nicht...
... 1-3 Takte sind durch die unterschiedliche Ausführungszeit der Instruktionen bedingt (1-4 clocks). Ein Interrupt Vektor wird erst am Ende der Instruktion ausgeführt.
Schreib dein Programm einfach so, dass es nur 1-Zyklen-Befehle verwendet ;-) Spaß beiseite: Es kommt letzendlich nicht nur auf die Interruptlatenzzeit an, sondern auch darauf, wie lange der Interrupthandler für die Ausführung einer entsprechende Reaktion braucht. Ist bei dir die Ausführungszeit des Interrupthandlers immer konstant? Wenn nein, bringt es auch nichts, die Interruptlatenzzeit optimieren zu wollen. Wenn ja, dann ist die ausgeführte Aktion so einfach, dass sie wahrscheinlich leicht auf anderem Wege zyklengenau realisierbar ist.
Das Problem sind doch meist die anderen, gerade aktiven, Interrups. Da muss man schnell EI() machen.
Hallo, der Interrupt selber ist immer von der Ausführungszeit her gleich lang. sichert das Serg Register er schaltet einen Portpin an und aus mit ein paar nop dazwischen und geht wieder Raus mit reti. Also kommen die Unterschiede auch durch das externe Signal zustande was ja zum Prozessor nicht synchron ist. Also der Interrupt wird ausgelöst aber der Prozessor arbeitet gerade noch einen Befehl ab und reagiert dann erst.
gibt es eine Möglichkeit immer die gleiche höchste Zeit einzuhalten also z.B ca. 10 Taktzyklen? Zählen der seit dem Interrupt vergangenen Zyklen und die zum PC addieren und springen am Anfang des Interrupts ein paar NOPS und dann die Einsprungadresse ändern nop ... nop bei 3 Zyklen hier reinspringen: nop bei 4 Zyklen hier reinspringen: nop ... nop serg sichern... ISR Reti wisst Ihr wie ich meine?
dann musst du wohl den interrupt von einem anderen controller ausführen lassen, der nichts anderes macht, als auf darauf zu warten
René Schink wrote:
...
> wisst Ihr wie ich meine?
ja, ich denke schon. aber du weiß ja nicht, welchen befehl die alu
gerade abarbeitet, wenn der interrupt kommt. er ist ja eine asynchrone
anforderung. das geht also ohne weiteres nicht.
du kannst ein eigenes os aufsetzen, das weiß, was es gerade tut, aber
das ist schon extrem aufwendig. lieber einen eigenen controller.
René Schink wrote: > Zählen der seit dem Interrupt vergangenen Zyklen und die zum PC addieren > und springen Das geht nur mit dem ICP-Interrupt. Damit kriegst Du den zyklusgenauen Zeitstempel des Interrupts und im Interrupthandler kannst Du dann die Zeitdifferenz zum durchlaufenden TCNT1 ermitteln und berücksichtigen. T1 muß dabei mit XTAL/1 laufen. Peter
Mal grundsätzlich: Man kann von einem Mikrocontroller, der bei 16MHz Befehlsausführungszeiten bis zu 0,25µs hat, dass er auf ein Signal mit einer Genauigkeit von 0,0625 µs reagieren kann. Wenn man das will sind Klimmzüge zu erwarten! Mein Vorschlag: 1. schnelleren Controller verwenden 2. diskrete Hardware / Counter IC verwenden 3. per timer0/software zählen und timer1 input capture register verwenden um die Abweichung zu kompensieren. (nicht empfehlenswert!)
Leider habe ich Timer 1 schon verbraten. Zu blöd das es nur einen Timer mit der Funktion gibt.
Wär aber doch mal interessant zu erfahren, für welches Problem eine Forderung nach taktzyklen-identischer Interrupt-Sprungzeit relevant sein soll.
Zum Beispiel bei zeitlich kritischer Anlieferung / Abholung von Daten an einem Bus - das Problem hatte ich auch schon. Es ließ sich nur durch entsprechend breite Zeitfenster der Datenvalidität in den Griff bekommen.
René Schink wrote: > Leider habe ich Timer 1 schon verbraten. Zu blöd das es nur einen Timer > mit der Funktion gibt. Das ist doch die gleiche Sache, für die Du ihn verbraten hast. Du mußt ihn nur auf ICP umstellen, dann kannst Du im ICP-Interrupt zählen. Peter
Hallo, Ich Zähle aber eien externen Takt an Pin B 1 der auch im Interrupt weiterzählt wird. Takt1 ___|--|_________*PIN AN-AUS*_______ | | . Die Zeit muß immer gleich sein (20xnop) .9xnix . . Takt10 ___|--|_________*PIN AN-AUS*_______ usw.
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.