Archiv verlassen und diese Seite im Standarddesign anzeigen : Verständnisfrage zum Thema Interrupts (mega64)
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
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
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
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
okay, dann versuche ich mal eine anderen lösung zu finden, außer mit "break"...
Danke
Gruß
popi
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
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.
@PicNick
Ich glaube soweit will popi nicht eintauchen, siehe "Schleifen parallel abarbeiten ???"
sast
Ich glaube soweit will popi nicht eintauchen, ..
'is beruhigend :mrgreen:
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
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
Vielen Dank für die tollen Beispiele!!!!
Daraus kann ich eine schöne Lösung konstuieren.
Grüße
popi
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.