PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupte schachteln ? ATmega128



olby2
10.10.2008, 10:06
Hallo Leute,

ich habe ein Programm mit mehreren ISR - Routinen geschrieben.

Eine Routine ist dabei recht lang geworden und wird dazu noch alle 13,33 ms aufgerufen,
(damit meine berechnungen auch regelmäßig gemacht werden PID et. )

Dazu kommen noch sehr kleine Routinen, die Zählerüberlauf signalisieren, einen Incrementalgeber abfragen etc.

Ich habe nun das Problem , dass in der Zeit, in der die Berechnungsroutine bearbeitet wird, keine anderen Interrupte bearbeitet werden können und mir somit z.B. Schritte meines Motors flöten gehen.

Gibt es einen Trick, um innerhalb einer ISR weitere Interrupte zuzulassen ?

vielen dank

olby2

MeckPommER
10.10.2008, 10:13
Nein, das geht nicht. Interrupts haben eine bestimmte Priorität. Sie gehen dir evtl. auch nicht verloren, werden aber erst nach Beendigung der laufenden ISR ausgeführt.

Generell sollte man darauf achten, Programmteile in ISR so kurz wie möglich zu halten. Es empfiehlt sich, hier nur Flags zu setzen und auf diese dann im Hauptprogramm zu reagieren.

Was bezeichnest du als "lange" Routine? Gibts vielleicht die Möglichkeit, hier noch etwas zu optimieren in Bezug auf die Ausführungsgeschwindigkeit? (z.B. Vorausberechnungen oder Assembler)

Gruß MeckPommER

Besserwessi
10.10.2008, 13:25
Man kann in der ISR Interrupts wieder freigeben. Wenn möglich sollte man das aber vermeiden, denn es ist recht fehleranfällig. Auf alle Fälle sollte man vermeiden das der Selbe Interrupts nochmal auftritt bevor er zuende ist.
BASCOM sichert ziehmlich viele Register in der ISR, man braucht also ein paar extra Bytes an Platz auf dem HW Stack.
Die Interruptsprioritäten haben da nicht viel mit zutun. Beim AVR geben die nur an welche ISR zu erst ausgeführt wird, wenn mehrere Interrupts zur Ausführung anstehen.

oberallgeier
10.10.2008, 13:53
... mehreren ISR - Routinen geschrieben ... Eine ... ist dabei recht lang ... wird ... alle 13,33 ms aufgerufen, (... PID et. ) ...Wenn ich Interrupts plane, dann halte ich die ISR so kurz wie möglich und ich habe auch noch nie nested interrupts benutzt, nicht wissentlich (ja, mal als Pannenfall *gggg*). Da ist schon etwas Gehirnschmalz und auch gelegentlich Experiment angesagt. Ob so eine lange ISR wie Deine sinnvoll ist, wage ich fast zu bezweifeln.


... wird ... alle 13,33 ms aufgerufen ...Für einen PID ist diese Frequenz sicher nicht allzu schnell - aber da Du schreibst, dass Du noch etliche andere hast, werden das bestimmt nie 13,33 ms, ich vermute, dass das in der Zielumgebung deutlich langsamer und ungleichförmiger wird. Dann stimmt eben auch die ganze Regelung nicht, weil anzunehmen ist (ich gehe bei meinen Planungen jedenfalls für mich immer davon aus), dass die verschiedenen ISR sich gegenseitig stören könnten. Und der digitale Regler hat sowieso ein Zeitglied, weil die Regelung zumindest bei den hier üblicherweise verwendeten Controllern mit einer "alten" Geschwindigkeitserfassung arbeiten muss. Wenn dann das jeweilige Alter schwankt und die Regelfrequenz noch dazu - - oh heiliger Regulus.

Ich habe einen PI-Regler (https://www.roboternetz.de/wissen/index.php/Regelungstechnik#Realisierung_mit_digitalem_Regler ) in einer ISR implementiert. Problem: Rechenzeit mit floating point *ggrrrrr* war zwei bis drei Millisekunden (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=388755#388755) . Also habe ich das Ganze in Integer gemacht, ein bisschen popeln, ein bisschen tricksen, ein bisschen mal grob schätzen und die gemessenen Reglerkonstanten hinschummeln, viel testen und - läuft prächtig (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=390196#390196)! ! weniger als 50 µS bei 20 MHz ... und das regelt zwei ziemlich unterschiedliche Motoren sehr sauber auf Gleichlauf bei gleichen Sollwerten. Regelfrequenz für jeden einzelnen Motor rund 100 Hz, die Motoren werden bei versetzten ISR-Aufrufen bedient, um die ISR nicht zu lange dauern zu lassen.

Wenn Du das mit den nested interrupts realisierst, dann berichte aber bitte über Deine Erfahrungen. Ich lerne gerne dazu.

Viel Erfolg

olby2
10.10.2008, 22:50
Ich habe eine Lösung gefunden.

In der "Haupt"-ISR Routine habe ich in der 2. Zeile

"Enable Interrupts" eingefügt und schon kommen auch weitetere Interrupte innerhalb der
"Haupt"-ISR
( mit dem Oszi nachgewiesen )
läuft super :-)

olby2

markusj
10.10.2008, 22:56
Und falls zweimal der selbe Interrupt kommt, stürzt du ab.

mfG
Markus

olby2
10.10.2008, 23:06
Und falls zweimal der selbe Interrupt kommt, stürzt du ab.

mfG
Markus

Das ist zwar richtig, doch sollte kein problem sein.
meine "Haupt-ISR" ist 1,5 ms lang und wird alle 13,33 ms aufgerufen und die anderen Interupt-Routinen sind je nur 2-3 Zeilen lang
Sollte also rein rechnerisch kein Problem sein - läuft jetzt auch schon mehrere Stunden am Stück ohne Fehler.

gruß
olby2

Besserwessi
11.10.2008, 00:00
Schon bei einzelnen Interrupts ist die Fehlersuche relativ schwierig, besonders bei sporadischen Fehlern, bei verschachtelten Interrupts macht die Fehlersuche gleich noch mal mehr Spass.
Aber solange es geht ist ja gut.

oberallgeier
11.10.2008, 00:31
... Sollte also rein rechnerisch kein Problem sein ...Viele (die meisten?) Unfallberichte beginnen etwa so:

Die Sache war gut überlegt und eigentlich hätte nichts passieren dürfen . . .