PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verständnisfrage zum Thema Interrupts (mega64)



popi
15.06.2006, 12:31
Hallo zusammen,

ich hätte mal eine Verständnis frage zu Interrupts.

Ich habe in meinem Programm zwei Schleifen.
Nun will ich, dass wenn ein Signal an einem bestimmten Pin ankommt, die eine Schleife durchlaufen wird und bei einem anderen Interrupt die andere Schleife.

Nun ist das doch so, das sich ein Interrupt die Adresse merkt, wo er rausgesprungen ist und setzt dann dort weiter fort.

Und genau das möchte ich nicht. Ich möchte, das der Controller dann die andere Schleife solange durchläuft, bis wieder der erste Interrupt die erste Schleife aktiviert usw....

Ist sowas überhaupt möglich oder muss nach einem Interrupt zurückgesprungen werden??

Danke und Grüße

popi

sast
15.06.2006, 13:12
Idee: Eine Endlosschleife enthält zwei innere Schleifen. Eine Variable (für die Abbruchbedingung) muss für die eine Schleife 0 sein und für die andere ungleich 0. Wenn du die Variable in den Interrupts setzt bzw. rücksetzt, musst du maximal den Schleifendurchlauf der aktuellen Schleife abwarten. Außer du baust noch breaks ein, wenn dein Code in den Schleifen zu lang ist.

sast

popi
16.06.2006, 10:26
Hallo sast,

klinkt gut, danke für Deinen Vorschalg.

Was sind den brakes? Kann man festlegen, nach welcher Bedingung man eine Schleife verlässt?
Also wenn Bedingung eintrifft, dann while-Schleife raus!

Werde man den Syntaxt versuchen zu ermitteln und dieses dann einzusetzen.

Danke nochmal und ggf. bis später ;o)

popi

sast
16.06.2006, 10:41
Ja, du kannst Schleifen auch vorzeitig verlassen. Ist aber unter Vorbehalt zu benutzen, da breaks einerseits einen unschönen Code zur Folge haben und andererseits ja immer mit einem Vergleich in Zusammenhang stehen, und bei kurzen Codesequenzen bläht es die Abarbeitung eher auf, als dass es einen Zeitvorteil bringt. Die Verwendung muss man von Fall zu Fall abwägen.
Ich will dich auf keinen Fall anstiften breaks zu verwenden.

sast

popi
16.06.2006, 11:40
okay, dann versuche ich mal eine anderen lösung zu finden, außer mit "break"...

Danke

Gruß

popi

sast
16.06.2006, 12:05
irgendwie werde ich den Eindruck nicht los, dass du nur mit Endlosschleifen arbeitest. Deshalb hier mal eine kurze Anleitung.

Beispiel 1: //a wird in den Serviceroutienen gesetzt

int a;
while(1)
{
while(a){//code}
while(!a){//anderer code}
}

Beispiel 2: //wenn der code sehr lang ist in den Schleifen
// nur mit Endlosschleifen

int a;
while(1)
{
while(1)
{
//code
if(!a)break;
//code geht weiter
}
while(1)
{
//anderer code
if(a)break;
//code geht weiter
}
}

Beispiel 3: //eine Mischung aus beiden

int a;
while(1)
{
while(a)
{
//code
if(!a)break;
//code geht weiter
}
while(!a)
{
//anderer code
if(a)break;
//code geht weiter
}
}

Im Normalfall würde ich hier Beispiel 1 nehmen

sast

PicNick
16.06.2006, 12:16
Es kommt darauf an, wie komfortabel du die Sache machen willst.
Wenn es genügt, daß das Umschalten auf eine andere Schleife darin besteht, daß sie einfach oben beim "while(1)" angesprungen wird, brauchst du nur die Adresse am Stack zu fälschen.
Wenn eine Schleife aber immer genau an dem Punkt mitten drin angesprungen werden soll, wo sie das letze mal untebrochen worden ist, wird das etwas aufwendiger.

sast
16.06.2006, 12:26
@PicNick
Ich glaube soweit will popi nicht eintauchen, siehe "Schleifen parallel abarbeiten ???"

sast

PicNick
16.06.2006, 12:29
Ich glaube soweit will popi nicht eintauchen, ..

'is beruhigend :mrgreen:

popi
16.06.2006, 12:29
Super... vielen Dank...

habe das sofort in meine kleine Anfängerformelsammlung aufgenommen!
und werde es wohl doch so in meinen Code einarbeiten ;o) ist jetzt mal zu Testzwecken schneller, Codeoptimierung folgt dann in der Phase 2 ;o)

Momentan komme ich sowieso nicht weiter... habe schon ein neues Problem gepostet.
Ich kann mein Projekt nicht mehr Compilieren.
Komischerweise meckert der Compiler nicht direkt, nur wenn man es Simulator abspielen möchte, sieht man, das es die erwänte Zeile nicht compiliert, warum auch immer...

Wenn ich damit durch bin, werde ich mal die brakes ausprobieren.

Gruß

popi

vajk
16.06.2006, 12:41
hmmm ...
nun Du mußt ja in der Interruptabarbeitung jeweils nur ein Flag setzen.
aber vergiss nicht, das globale flag als volatile zu deklarieren:
volatile byte flag = 0;

Je nachdem, was Du in den Schleifen abarbeiten lassen willst, wäre auch eine andere Methode (als die 3 while-Schleifen im B eitrag zuvor) über switch möglich, so kannst Du bei jedem Schritt auf Abbruch prüfen ...



**verkürzte schreibweisen**

volatile byte flag = 0;

INT_1 { flag = 10; }
INT_2 { flag = 100; }

void main(void)
{
for(;;)
{
switch(flag)
{
case 0 : {Init und am Ende: flag = 10;} break;

case 10 : {tue was und am Ende: flag = 11;} break;
case 11 : {tue was und am Ende: flag = 12;} break;
case 12 : {tue was und am Ende: flag = 13;} break;
case 13 : {flag = 10;} break;

case 100 : {tue was und am Ende: flag = 101;} break;
case 101 : {tue was und am Ende: flag = 102;} break;
case 102 : {tue was und am Ende: flag = 103;} break;
case 103 : {tue was und am Ende: flag = 104;} break;
case 104 : {flag = 100;} break;
}
}
}


Somit wird Schritt für Schritt abgearbeitet, kann aber jederzeit gewechselt werden .... und du könntest flag 0 .. 10 auch dafür nutzen, was einleitendes zu tun = Initialisierung von was auch immer.

Du könntest Dir auch den alten Werte vor änderung merken und so an nach "Schleifenwechsel" wieder an der Stelle weitermachen, wo unterbrochen wurde ...

Wenn Du über die Schleifen z.B. Schrittmotoren steuerun wolltest, könntest die Hauptschleife auch in einen Timerinterrupt packen und mit einem Vorteiler, die Taktfrequenz verändern = Beschleunigung und Abbremsvorgang ...

Idee verstanden ?

Hope it helps,
Vajk

popi
16.06.2006, 14:23
Vielen Dank für die tollen Beispiele!!!!

Daraus kann ich eine schöne Lösung konstuieren.

Grüße

popi