PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Datenaustausch mit Interrupt-Routinen



Toastbrot
17.01.2006, 20:44
Hallo,
ich habe in meiner main() ein Menü aufgebaut, dass verschiedene unterfunktionen aufruft. Funktioniert alles soweit, allerdings wird nach einem Interrupt nicht an die richtige Stelle gesprungen.

Daher habe ich vor der main() noch 2 volatile Varibalen deklariert


volatile int8_t agrobot; //Menü-Ziffer
volatile int8_t agrobot2; //Vorherige Menü-Ziffer


Der Interrupt soll nun "agrobot2" mit der aktullen Menü-Ziffer belegen, aus der er gerade raus gesprungen ist, anschließend wird "agrobot" mit einer neuen Ziffer belegt, die auskunft über die aufzurufende Funktion gibt.



SIGNAL (SIG_INTERRUPT0) //Auffahrschalter Front
{
agrobot2 = agrobot;
agrobot = MENU_backevade; //MENU... ist per define festgelegt
}//Auffahrschalter Front


Darauf soll das Hauptmenü die Funktion aufrufen, die vom Int. ausgelöst werden soll. Dieser wird als Parameter "agrobot2" übergeben, was anschließend einfach zurück gegeben wird, und somit als nächster Menüpunkt verwendet wird:



while(1) //Hauptschleife
{
//Aufgabe/Funktion abfragen

switch ( agrobot )
{
case MENU_error: agrobot = error(); //Fehlerausgabe
break;
case MENU_menu: agrobot = menu(); //Menü
break;
//...weitere Menüpunkte
case MENU_backevade: agrobot = backevade(agrobot2); //Rückwärts ausweichen
break;
case MENU_frontevade: agrobot = frontevade(agrobot2); //Vorwärts ausweichen
break;
}

}//Hauptschleife


Wird alles soweit kompiliert, allerdings passiert beim Auslösen des Interrupts nichts.

Kann mir da jemand helfen wo der Fehler liegt, oder sagen wie es besser geht?

Ich hoffe das ist nicht zu speziell und ich habe mich vernünftig ausgedrückt ;)

askazo
18.01.2006, 08:16
Ich denke mal das Problem ist, dass Du in der switch-Anweisung die Variable agrobot mit neuen Werten belegst. agrobot bekommt seinen Wert doch von der Interrupt-Routine, und die switch-Anweisung soll nur die passende Funktion aufrufen, oder?
Dann müsste die Hauptschleife so aussehen:
while(1) //Hauptschleife
{
//Aufgabe/Funktion abfragen

switch ( agrobot )
{
case MENU_error: error(); //Fehlerausgabe
break;
case MENU_menu: menu(); //Menü
break;
//...weitere Menüpunkte
case MENU_backevade: backevade(agrobot2); //Rückwärts ausweichen
break;
case MENU_frontevade: frontevade(agrobot2); //Vorwärts ausweichen
break;
}

}//Hauptschleife

Toastbrot
18.01.2006, 09:25
Aber es werden nur die beiden Funktionen durch die Interrupts aufgerufen, die anderen werden später per Abfrage eines ADC Ports und daran angeschlossenen Tastern mit Widerständen (ähnlich RN-Control) gesetzt.

Wobei ein ADC Port kann auch ein interrupt auslösen, oder? Dann braucht in der main() wirklich kein Wert zugewiesen werden.

Sehe ich das richtig?

fambi_mail
21.02.2006, 18:21
Probleme gibt es hauptsächlich bei Variablen die größer als ein Byte sind.

SprinterSB
21.02.2006, 21:12
In der Hauptschleife überschreibst du möglicherweise den Wert von agrobot, weil sowohl die ISR als auch in main (oder Unterfunktionen) der Wert gesetzt wird. Überleg dir genau, welcher Teil die Variable setzen darf, und welcher sie "konsumiert".

Das Konsumieren könnte so gehen:

uint8_t agro;
uint8_t sreg = SREG;
cli();
if (agrobot != leer)
{
agro = agrobot;
agrobot = leer;
}
SREG = sreg;

ruediw
21.02.2006, 22:52
Ich würde in der ISR *** nie *** Variablen deklarieren, die man im Hauptprogramm oder von einer anderen ISR lesen oder schreiben will !!

SprinterSB
23.02.2006, 08:35
Wo die Deklaration steht ist doch egal. Besserer Stil ist natürlich, die Delaration im Header zu machen.

Warum sollte man nicht Daten über eine Variable/Struktur/Obkekt zwischen ISR und Applikation austauschen?

argentan
23.02.2006, 10:49
Moin!

Wo die Deklaration steht ist eben NICHT egal.
Wie war das noch mit lokalen und globalen Variablen?
Genau! Deklariert man eine Variable lokal, sprich in einer Funktion (und die ISR ist eine Funktion), dann wird auf die lokale Variable zugegriffen. Eine eventuelle globale Variable gleichen Namens wird ignoriert! Somit bleiben die Daten in der ISR und können nicht von anderen Programmteilen gelesen und bearbeitet werden.

Also die Variablen zum Datenaustausch von ISRs immer global definieren.

MfG Argentan

SprinterSB
23.02.2006, 17:17
Du meinst die Definition (das ist was anderes als eine Deklaration).

Du kannst auch mit einem lokal gultigen Symol auf eine globale Variable greifen:

void foo()
{
extern int blah;
}