- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 9 von 9

Thema: Datenaustausch mit Interrupt-Routinen

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.12.2004
    Ort
    /dev/urandom
    Beiträge
    129

    Datenaustausch mit Interrupt-Routinen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    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
    Code:
    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.

    Code:
    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:

    Code:
    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
    Hilfe, wo ist die Anykey-Taste?

    <- Projekt Agrobot ->

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    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:
    Code:
    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

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.12.2004
    Ort
    /dev/urandom
    Beiträge
    129
    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?
    Hilfe, wo ist die Anykey-Taste?

    <- Projekt Agrobot ->

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    24.03.2005
    Beiträge
    21
    Probleme gibt es hauptsächlich bei Variablen die größer als ein Byte sind.

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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:
    Code:
    uint8_t agro;
    uint8_t sreg = SREG;
    cli();
    if (agrobot != leer)
    {
       agro = agrobot;
       agrobot = leer;
    }
    SREG = sreg;
    Disclaimer: none. Sue me.

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.12.2005
    Ort
    Tann / ZH
    Alter
    67
    Beiträge
    264
    Ich würde in der ISR *** nie *** Variablen deklarieren, die man im Hauptprogramm oder von einer anderen ISR lesen oder schreiben will !!
    MfG
    Ruedi

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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?
    Disclaimer: none. Sue me.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    13.10.2005
    Beiträge
    25
    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

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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;
    }
    Disclaimer: none. Sue me.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test