- Labornetzteil AliExpress         
Ergebnis 1 bis 8 von 8

Thema: kann globale variable nicht im interrrupt beschreiben

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.12.2014
    Beiträge
    6

    Frage kann globale variable nicht im interrrupt beschreiben

    Anzeige

    E-Bike
    Hallo Leute,
    Ich will für den Nibobee ein Odometriesystem schreiben und stoße dabei auf ein kleines Problem:
    Ich kann eine globale Countervariable nicht korrekt beschreiben.

    Code:
    // mit und ohne static, sowie auch ohne volatile negativ getestet
    /*static*/ volatile unsigned  int odometry_count_r=0;
    /*static*/ volatile unsigned  int odometry_count_l=0;
    
    /* wenn etwas überläuft, wird das ausgeführt */
    // mit und ohne volatile getestet
    /*volatile*/ void ( * odometry_l_overflow)(void);
    /*volatile*/ void ( * odometry_r_overflow)(void);
    
    
    ISR(INT0_vect)
    {
    // u.U. muss man das nicht atomisch machen
    //      sei();
            odometry_count_l++;
            #ifdef __TEST
            set_led(LED_L_Y,1);
            _delay_ms(20);
            set_led(LED_L_Y,0);
            #endif
            // eigentlich 0, da dann ein ueberlauf da ist, 3 zum testen.
            if(odometry_count_l==3)
            {
                    odometry_l_overflow();
            }
            reti();
    }
    // analog dazu vect1
    
    void _init_odometrie(void)
    {
            GICR|= 1<<INT0;
            GICR|= 1<<INT1;
            MCUCR|= 1<<ISC01 | 1<<ISC00;
            MCUCR|= 1<<ISC11 | 1<<ISC10;
            sei();
            #ifdef __TEST
            // lauffeuer laesst leds der reihe nach blinken.
            odometry_l_overflow=lauffeuer;
            odometry_r_overflow=lauffeuer;
            #else
            odometry_l_overflow=nop;
            odometry_r_overflow=nop;
            #endif
    
            #ifdef __TEST
            _init_led();
            #endif
    }
    
    void nop(void)
    {
            asm("nop");
    }
    Aber es wird nie odometry_l_overflow ausgeführt. Eigentlich sollte auch der Speicher nicht korrumpiert sein
    und der Funktonspointer funktioniert auch. Die ganzen Led-Sachen sind nur da um zu sehen wann der Interrupt ausgelößt wurde.

    Danke im Vorraus
    LittleBoy

  2. #2
    shedepe
    Gast
    Also ein paar Sachen:
    1. Warum rufst du in einem Interrupt sei() auf.
    2. reti() brauchst du wenn du mit einem Atmega arbeitest nicht. -> Hier wird sogar gesagt (http://cboard.cprogramming.com/c-pro...-function.html) dass das Programm dann crashen kann.
    Siehe dazu auch: http://www.nongnu.org/avr-libc/user-...e31f9a6d10533b

    Ich vermute mal, dass es funktioniert wenn du reti() weglässt.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.12.2014
    Beiträge
    6

    Solved, Danke

    Ja ok das reti() hat alles kaput gemacht.
    Danke!
    btw:
    das sei() ist da, damit ich lange Prozeduren nicht atomisch ausführen kann.
    Das wird dann per Variable ein und aus geschaltet.

  4. #4
    shedepe
    Gast
    Das sei bewirkt in dem Interrupt absolut gar nichts. Wenn das System in den Interrupt gesprungen ist, dann sind die interrupts bereits aktiv.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    27.12.2014
    Beiträge
    6

    Ausrufezeichen

    tja jetzt funktioniert es immer noch nicht so ganz:
    ich habe zwei variablen eingefügt, die wie ein timer compare interrupt funktionieren sollen,
    allerdings kann ich die nicht immer erfolgreich beschreiben:
    Code:
    static volatile unsigned int odometry_count_r=0;
    static volatile unsigned int odometry_count_l=0;
    // auch static getestet
    volatile unsigned int odometry_comp_r=0;
    volatile unsigned int odometry_comp_l=0;
    
    /*wie gesagt compare */
    void ( * odometry_l_comp)(void);
    void ( * odometry_r_comp)(void);
    
    
    ISR(INT0_vect)
    {
            odometry_count_l++;
            #ifdef __TEST
            set_led(LED_L_Y,1);
            _delay_ms(20);
            set_led(LED_L_Y,0);
            #endif
            
            if(odometry_count_l==odometry_comp_l)
            {
                    odometry_l_comp();
            }
    }
    void _init_odometrie(void)
    {
            if(add_mod(_MOD_ODO));
            {
                    GICR|= 1<<INT0;
                    GICR|= 1<<INT1;
                    MCUCR|= 1<<ISC01 | 1<<ISC00;
                    MCUCR|= 1<<ISC11 | 1<<ISC10;
                    sei();
                    #ifdef __TEST
                    odometry_l_comp=lauffeuer;
                    odometry_r_comp=lauffeuer;
                    #else
                    odometry_l_comp=nop;
                    odometry_r_comp=nop;
                    #endif
    // das wuerde funktionieren
    //              odometry_comp_l=5;
    //              odometry_comp_r=5;
    
    
             }
    }
    
    // aus odtest.c
    
    int main(void)
    {
    // funktioniert nicht.
            odometry_comp_l=5;
            odometry_comp_r=5;
    //auch andersherum getestet
            _init_odometrie();
            while(1);
    }
    irgendwie kommt mir das komisch vor.
    Danke in Vorraus
    LittleBoy

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    21.06.2011
    Ort
    Dresden
    Beiträge
    219
    hi,
    hast Du die beiden Variablen im Modul odtest.c mit extern deklariert ?
    mfg
    Achim

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    27.12.2014
    Beiträge
    6
    nein,
    da ich die Variablen in odometrie.h definiert habe und in odotest.c mit `#include"odometrie.h"`
    eingebunden habe, genauso wie in
    odometrie.c, wo die Funktion `_init_odometrie()` drin ist.
    Das ist das was mich ja so wundert.
    lg
    LittleBoy

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    Eine Variable im Header kann gar nicht funktionieren. Da würde ein normaler, funktionierender Compiler sofort melden, dass "multiple definitions" vorhanden sind und abbrechen.

    Pack die Variablen als static ins source-file und implementiere Funktionen zum ändern.

    Code:
    inline void IncrOdoCount();
    inline int GetOdoCount();
    etc...
    Dann hast du eine funktionierende, saubere und Design-konforme Lösung. Globale Variablen sind sch*****!!

    mfg

Ähnliche Themen

  1. [VHDL] Globale Variable/Signal?
    Von redraven im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 12
    Letzter Beitrag: 20.12.2010, 15:39
  2. [erledigt] globale Variable in ISR ändern + im Hauptprogramm
    Von grumpf im Forum C - Programmierung (GCC u.a.)
    Antworten: 29
    Letzter Beitrag: 11.02.2008, 13:53
  3. Antworten: 7
    Letzter Beitrag: 04.10.2006, 17:06
  4. globale Variable und Interrupt
    Von a//b im Forum C - Programmierung (GCC u.a.)
    Antworten: 12
    Letzter Beitrag: 04.08.2006, 19:45
  5. Warum kann ich keine AVRs mehr beschreiben?
    Von Gottfreak im Forum AVR Hardwarethemen
    Antworten: 12
    Letzter Beitrag: 26.03.2004, 11:09

Stichworte

Berechtigungen

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

Solar Speicher und Akkus Tests