Forum: Mikrocontroller und Digitale Elektronik Interrupt und Hauptprogramm


von Mr.Burns (Gast)


Lesenswert?

Hallo,

habe einen Atmega8 und werte über INT0 eine externen Interrupt aus.
In der Interrupt-Routine zähle ich einen 16 Bit Zähler hoch (mit 
volatile deklariert), wenn eine aufsteigende Flanke auftritt.
Im Hauptprogramm kopier ich mir dann den Wert des Zählers in eine lokale 
Variable und möchte damit dann im Hauptprogramm weiterarbeiten.
(Das Kopiern der 16Bit Variable in die lokale Variable des 
main-Programms passiert in einer atomaren Operation).
Nun möchte ich immer wenn sich der Wert der lokalen Varible ändert eine 
Aktion ausführen. Der Code für diese Aktion ist zu groß um dies in der 
Interrupt-Routine zu machen.
Nun müsste ich ja im Hauptprogramm ständig vergleichen, ob sich der Wert 
der lokalen Variable geändert hat um dann meine Aktion auszulösen.
Dadurch habe ich aber dann die Main-Schleife zu 100% mit dieser Aufgabe 
'belastet'. Der Vorteil, den ich mir über die Interrupt-Routine 
ermöglicht habe (nur zu reagieren, wenn eine Flanke an INT0 anliegt und 
main somit zu entlasten) habe ich mir damit wieder kaputt gemacht.
Wie kann ich so etwas nun elegant lösen?
Möchte also eine komplexe Funktionalität ausführen, nur wenn an INT0 
eine Flanke auftritt. In der INT-Routine kann ich den Code nicht packen, 
weil der zu komplex und zu groß ist. Im Hauptprogramm dann über while(1) 
ständig das ändern des Zählers prüfen würde aber die Interrupt-Routine 
überflüssig machen.

Danke für Eure Hilfe!

von Purzel H. (hacky)


Lesenswert?

Ich wuerd eine volatile boolean setzen und die abfragen.

von benwilliam (Gast)


Lesenswert?

wenn die main methode sonst nichts zu tun hat ist das doch ok o.O?

von Ulrich (Gast)


Lesenswert?

Das mit dem zu groß und zu komplex für den Code im Interrupt ist immer 
relativ. Wenn sonst nichts anliegt, kann der ISR code sich auch viel 
Zeit lassen, und hinsichtlich Größe gibt es gar eine extra Begrenzung.

Ein Möglichkeit wäre es eine 2. zusätzliche ISR (als Quasi 
softwareInterrupt) nutzen, die relativ früh nach einem ggf. kritischen 
Teil interrupts wieder freigibt. In der ISR von Int0 müsste dann nur 
noch geprüft werden ob die zusätzliche ISR noch läuft. Wie man den Fall 
behandelt das die Routine noch nicht fertig ist, wenn das nächste Signal 
kommt, ist unabhängig davon wie man das ganze löst.

von Karl H. (kbuchegg)


Lesenswert?

Mr.Burns schrieb:

> Dadurch habe ich aber dann die Main-Schleife zu 100% mit dieser Aufgabe
> 'belastet'.

Nö. Das ist aber eine Milchmädchenrechnung.

Wenn deine Hauptschleife sonst nichts anderes tut, als diese 
Flankenauswertung zu machen, dann ist klar, dass sie zu 100% ausgelastet 
ist. Sie tut ja sonst nichts anderes.

Wenn die Hauptschleife auch noch eine zweite Aufgabe hat, dann teilt 
sich die Rechenzeit innerhalb der Schleife auf die beiden Aufgaben auf 
und du überprüfst eben nicht mehr 100% der Zeit ob eine Flanke vorlag, 
sondern machst hauptsächlich das andere (weil die Flankenauswertung 
schnell geht und fast keine Zeit beansprucht)


> Im Hauptprogramm dann über while(1)
> ständig das ändern des Zählers prüfen würde aber die
> Interrupt-Routine überflüssig machen.

Du hast gut erkannt, warum man für zb Tastenauswertung keinen Interrupt 
braucht.

Die komplexe Funktionalität eventuell in Einzelabschnitte aufteilen, die 
nacheinander von der Hauptschleife abgearbeitet werden. Damit bist du 
auf dem Weg eine Zustandsmaschine zu realisieren.

von Oliver (Gast)


Lesenswert?

Mr.Burns schrieb:
> Der Code für diese Aktion ist zu groß um dies in der
> Interrupt-Routine zu machen.

Nun ja, machen musst du die Aktion trotzdem. Solange du keine anderen 
Interrupts oder gepollte Reaktionen auf externe Ereignisse nutzt, ist es 
dann auch egal, ob das in der ISR oder in main passiert.
Ansonsten brauchst du eine mainloop, die garantiert schneller läuft, als 
die Flanken kommen. Die kann dann auf ein Flag aus der ISR reagieren.

Und last but not least, wenn deinen Aktion zeitlich nicht zwischen zwei 
Flanken passt, dann passt die nicht, eal, ob in der ISR oder in main.

Oliver

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.