Hallo zusammen, ich nutze die beiden Interrupteingänge des AVR (INT0/1). Was muss ich unternehmen, damit der uC wirklich auf alle Flankenwechsel der Eingänge reagiert, auch wenn sie absolut zeitgleich auftreten? (Test: beide Eingänge parallel schalten) Oder besser allgemein gefragt: Nach welcher Priorität löst der AVR bei zeitgleichen Auftreten (sofern nicht auf Systemtakt zurückzuführen) welche Interrupts aus? Wann besteht die Gefahr ein Ereignis zu verpassen und was tut man dagegen? Viele Fragen, aber meist unbeachtet bzw. für mich insbesondere beim AVR noch etwas undurchsichtig - hoffe auf Eure Antworten .. Viele Grüße Tim
Die Priorität ergibt sich beim AVR aus der Position in der (nicht änderbaren) Interrupt-Tabelle. Damit keine Interrupts "verloren" gehen sind die Interrupt-Service-Routinen so kurz wie möglich zu halten. Alternativ kann man auch weitere Interrupts innerhalb einer ISR zulassen und diese auch die entsprechendes Setzen der Maskenregister auf einzelne INT beschränken.
@mmerten Wenn also mehrere Interrupts absolut zeitgleich auftreten, wird der erste Eintrag in der Interrupttabelle angesprungen?. Was passiert jedoch dann mit meinen anderen Ereignissen? -werden sie intern in einem FF zwischengespeichert und man kann sie irgendwie abfragen oder gehen sie verloren? Selbst die kürzeste Interruptroutine würde den 'zeitgleichen Fall' meiner Meinung nicht lösen.
Hallo! Ich bin mir nicht ganz sicher, müsste noch mal ins Datenblatt sehen, aber wenn ein Interrupt abgearbeitet wird, sind die anderen Interrupts normalerweise gesperrt. Die werden aber nicht vergessen, sondern im Int-Flag gespeichert und nach dem Wiederfreigeben der Ints abgearbeitet. Wenn also nicht ein Int mehrfach auftritt, während ein anderer noch bearbeitet wird, kann nichts passieren. Man verliert also auch bei gleichzeitigen Ints (normalerweise) keinen Interrupt. Schöne Grüße Peter
Doch, meines Wissens schon mehr. Bloß wie erwähnt nacheinander, der Priorität nach. Ich spreche davon, falls mehrere zeitgleich auftreten würden.
Hallo Tim, der AVR "vergisst" keinen Interrupt. Wenn mehrere Interrupt's gleichzeitig auftreten, werden die Routinen nach der Interrupttabelle behandelt. Zwischen jedem Interrupt wird noch ein Befehl Deines Hauptprogramms abgearbeitet. Bernhard
Hallo Berhard, wenn's wirklich so ist wie Du sagst brauche ich mir ja keine Gedanken mehr zu machen, wie ich den seltenen, aber möglichen Fall, in meinem aktuellen Projekt testen soll. Im AVR-Studio konnte ich die Problematik leider nicht nachvollziehbar nachsimulieren. Habe gerade nochmal in Ruhe im Datenblatt nachgelesen (2313/S.22). Dort scheint es auch so beschrieben zu sein, wie Du meinst - jedoch mit folgender Ausnahme: 'Note that external level interrupt (in diesem Fall wohl mein INT0/1) does not have a flag, and will only be remembered for as long as the interrupt condition is active' .. soll wohl heissen, dass wenn der AVR mit einem anderen normalen (internen) Interrupt beschäftigt ist (I-Flag zurückgesetzt), er das auftretende Ereignis an den INT0/1-Eingängen regelrecht ignoriert - von einem gleichzeitigen Auftreten an INT0/1 will ich erst gar nicht sprechen ... oder liege ich da falsch? Scheinbar habe ich jetzt noch ein größeres Problem, von dem ich noch gar nicht ausgegangen bin ...
Hallo Tim, Du hattest nach Flankenwechseln an INI0/INT1 gefragt; diese haben ein Flag, was beim Auftreten der Flanke gesetzt wird. Nichts geht verloren. Bei 'level interrupt' ist das auslösende Gerät/Bauteil dafür verantwortlich, den Pegel aktiv zu lassen, bis er bedient wird oder die Interruptanforderung nicht mehr benötigt wird. Läßt sich alles sauber verarbeiten.
.. soll also heissen, dass das Signal an INT0/1 solange Anliegen muss, bis der AVR das Ereignis verarbeitet hat. Müsste also ein D-FlipFlop vor die Eingänge hängen, die mir der uC in der INT-Routine über ein Out-Port später wieder zurücksetzt?
Nein. Beim 2313 z.B. kannst Du im MCUCR-Register festlegen, ob ein Flankenwechsel den Interrupt auslösen soll oder ein statischer 0-Pegel. Für die Flankenwechsel sind die D-FFs schon intern vorhanden; diese werden bei Aufruf der INT-Routine selbsttätig gelöscht. Sieh Dir bitte das betreffende Datenblatt Deines Prozessors an. Und vergiß alles, was Dir irgendwelche Simulationsprogramme anzeigen. Genucht !
Hallo Tim, wie auch Michael angedeutet hat, kann der Simulator nicht alle Interrupts korrekt abarbeiten. Obwohl die externen Interrupt sich mit einem STI-File exakt auslösen lassen. Deine Interpretation weiter oben ist nich ganz richtig. Dein Flankenwechsel wird nur dann nicht erkannt, wenn während des nächsten Ereignisses genau der dafür vorgesehene Interrupt noch läuft. Wer aber einen Interrupt länger abarbeiten lässt als die Ereignisfolge, sollte sich hinter die Ohren schreiben: Jeder Interrupt erledigt nur das allerallernötigste. Bedenke bei Deinen Timingüberlegungen, dass Dein Int0 auch durch einen anderen Int verzögert aufgerufen werden kann. Somit muss Deine Ereignissfolge immer noch langsamer sein. Bernhard
Hallo Bernhard, danke für Deine Hilfe. Werde die ganze Sache auf dem STK500 mal testen - ist ja schnell gemacht: Die beiden INT1/0 Eingänge schalte ich parallel und hänge sie an einen Taster. In den dazugehörigen Int-Routinen schalte ich dann jeweils eine LED ein. Zusätzlich richte ich noch eine Einschaltverzögerung mit einem Timerinterrupt ein, der eine 3.LED setzt und in dessen Verlauf ich solange hängen bleibe, bis ich eine weitere Taste drücke. Wenn jetzt nach dem Einschalten die 3.LED leuchtet, drücke ich den INT0/1-Taster. Wenn alle Theorien stimmen, müsste nach dem Ausstieg aus dem Timerinterrupt die beiden anderen LED's angehen. werde berichten, ob's so war Viele Grüße Tim
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.