- LiFePO4 Speicher Test         
Ergebnis 1 bis 8 von 8

Thema: Interrupt - Problem mit Schreibzugriff auf globale Variablen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    21.07.2008
    Ort
    Moosburg
    Alter
    45
    Beiträge
    49

    Interrupt - Problem mit Schreibzugriff auf globale Variablen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    ich habe ein Problem mit einer Interruptroutine. Über einen Timer soll u. a. eine Zählvariable inkrementiert werden. Irgendwie funktioniert da leider nicht, der Wert der Variablen ändert sich nicht.

    Ich habe das Programm mal auf folgendes Beispiel zusammenschneiden können, wobei der Fehler hier immer noch auftritt.

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile char count = 0;
    
    ISR(TIMER0_COMPA_vect) {
      count++;
      PIND = (1 << PD5);
    } 
    
    int main(int argc, char **argv) {
      // Hier wird Port D und Timer 0 initialisiert
    
      sei();
    
      // Timer 0 starten
    
      while (1)
        if (counter != 0)
          PORTD |= (1 << PD6);
      }
    }
    Der Timer 0 ruft alle 2.5 ms die obige Interrupt-Routine auf. Das kann ich auch mit meines Oszi am Pin PD5 schön verfolgen. Nur leider ändert sich an der LED am Pin PD6 nie etwas. Auch das Oszi zeigt keine Veränderung am Pin.

    Compiliert wird das ganze mit AVR-GCC unter Debian Linux.

    Kann mir jemand nen Tipp geben, woran's liegt, dass sich der Inhalt von counter nicht ändert? Ich seh grad die Bits vor lauter Bytes nicht mehr...


    Danke und viele Grüße,

    Markus

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Hi,

    • 1. "count" ist nicht gleich "counter"!
      2. nach dem Setzen von PD6 mit "PORTD |= (1 << PD6);" änderst Du PD6 nicht mehr


    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    21.07.2008
    Ort
    Moosburg
    Alter
    45
    Beiträge
    49
    Sorry, Tippfehler. Sollte wirklich "count != 0" heissen.

    Die Zeile "PORTD |= (1 << PD6);" stimmt so. Die LED an PD6 sollte angehn, wenn count einen anderen Wert als 0 einnimmt, was eigentlich nach 2.5 ms passieren sollte. Das tut's aber leider nicht, also muss ich davon ausgehen, dass count in der ISR nicht verändert wird.
    Der Port ist übrigens richtig initialisiert. Wenn ich count initial auf 1 setze, geht die LED an.

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Hi,

    dann poste doch mal Deinen Code mit Initialisierung usw. (als kompilierbare Version). Du hast gesehen, dass Abtippen nur zu Fehlern führt -- also "copy&paste".

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    21.07.2008
    Ort
    Moosburg
    Alter
    45
    Beiträge
    49
    Ok, ich hab gestern nochmal bisschen rumexperimentiert. Irgendwie bring ich das einfach nicht zum Laufen. Hier sit nochmal der vollständige und compilierbare Code:

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile unsigned char count;
    
    ISR(TIMER0_COMPA_vect)
    {
      PIND = (1 << PD5);
      count++;
    }
    
    void init_port()
    {
      PORTD = 0x00;
      DDRD = (1 << PD5) | (1 << PD6);
    }
    
    void init_timer()
    {
      // Timer 0
      TCCR0B = 0x00; 
      TCCR0A = 0x02;
      OCR0A = 0x32;
      TCNT0 = 0;
    
      // Interupt-Maske
      TIMSK = 0x01;
    }
    
    void start_timer()
    {
      TCCR0B |= 0x03;   // Timer mit 1:64-Prescaler starten
    }
    
    int main( int argc, char **argv)
    {
      count = 0;
    
      init_timer();
      init_port();
      sei();
      start_timer();
    
      while( 1)
        {
          if( count != 0)
    	PORTD |= (1 << PD6);
        }
    
      return 0;
    }
    Soweit ich das sehe, sollte die LED an PD5 abwechselnd 2,5ms leuchten und dunkel sein, während die LED an PD6 nach 5ms an geht und auch an bleibt. Die LED an PD5 reagiert wie erwartet, nur die an PD6 bleibt dunkel. Scheinbar wird die Variable count, obwohl als "volatile" deklariert, in der ISR nicht verändert.

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Hi,

    da ich nicht weiß, welchen Prozessor Du einsetzt, habe ich Dein Programm mal für den Attiny2313 mit dem AVRStudio simuliert (kompiliert mit WinAVR Dez 2007). Bei F_CPU=4 MHz geht PD6 etwa 0.84ms nach Programmstart von L auf H; PD5 wechselt etwa alle 0.84ms.
    • Vielleicht hat Deine Entwicklungsumgebung einen Bug?
      Bist Du Dir sicher, dass Du immer die neueste Version Deines Programms flashst?


    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    21.07.2008
    Ort
    Moosburg
    Alter
    45
    Beiträge
    49
    Controller ist ein ATtiny2313 bei 8 MHz.

    An die möglichen Bugs in Hard- und Software hab ich auch schon gedacht und mal verschiedene Programme geschrieben, um den Fehler eingrenzen zu können. Soweit ich sagen kann, ist das Board und der Controller definitiv in Ordnung.
    Seltsam ist, dass sich der Wert für count durch die ISR nicht ändern lässt. Wenn ich count in main() einen neuen Wert != 0 zuweise, geht die LED an PD6 an. Sind evtl. spezielle Kommandozeilenoptionen für gcc, avr-objcopy oder avrdude nötigt?

    Programmiert wird das Ganze mit avr-gcc und avrdude unter Linux.

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Wie gesagt: bei mir geht es (gcc Version Dez. 2007) mit dem Simulator des AVR-Studio (unter XP-SP2); "count" wird korrekt geändert und die Änderung in "main()" auch erkannt.

    Ich hatte neben den unsigned/short/bitfield-Parametern nur die folgenden Optionen gesetzt:
    -Wall
    -Os
    -gdwarf-2

    Hast Du mal nach Bugreports für Deine Entwicklungsumgebung gesucht?

    Gruß

    Fred

    Meldungen keim Kompilieren/Linken:
    avr-gcc.exe -mmcu=attiny2313 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT cipher.o -MF dep/cipher.o.d -c ../cipher.c
    avr-gcc.exe -mmcu=attiny2313 -Wl,-Map=cipher.map cipher.o -o cipher.elf
    avr-objcopy -O ihex -R .eeprom cipher.elf cipher.hex
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex cipher.elf cipher.eep || exit 0
    avr-objdump -h -S cipher.elf > cipher.lss
    Only entropy comes easy. - Anton Checkhov

Berechtigungen

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

Labornetzteil AliExpress