-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: ATMega8515: Problem mit Timer-Interrupt

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31

    ATMega8515: Problem mit Timer-Interrupt

    Anzeige

    Hallo Leute,

    leider konnte mir im Mikrocontroller Forum keiner helfen, deswegen probiere ich es hier noch einmal. Bitte habt Nachsicht mit diesem Cross-Posting.

    Problem: Einfacher Timer-Interrupt funktioniert nicht

    Folgender (simpler) Code:

    Code:
    #ifndef MCU             
    #define __AVR_ATmega8515__
    #endif
    
    #ifndef F_CPU           
    #define F_CPU 4000000UL
    #endif
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/portpins.h>
    #include <util/delay.h>
    
    ISR(TIMER0_OVF_vect)
    {
      PORTC = ~PORTC;
    }
    
    int main()
    {
      DDRA   =  0xff;
      PORTA   =   0x0f;
      
      DDRC  =   0xff;
      PORTC   =   0x0f;
      
      TIMSK  |=  (1 << TOIE0);                //overflow timer einschalten
      TCCR0   =  (1 << CS02) | (0 << CS01) | (1 << CS00);  //prescaler auf 1024
      
      //sei();      //hauptschleife funktioniert wenigstens wenn auskommentiert
      
      while(1)
      {
        PORTA = ~PORTA;
        _delay_ms(500);
      }
    }
    Effekt: Wenn der call auf sei() auskommentiert ist, funktioniert die Hauptschleife. Sonst geht gar nichts.

    Das Programm ist meines Erachtens nach absolut korrekt! Der Chip sitzt auf dem STK500 und soll dort die LEDs zum Leuchten bringen. Sobald der Call auf sei() drin ist, geht gar nichts mehr!

    Vermutung: Controller hängt permanent in der Interrupt-Routine oder ist gar defekt.

    Frage: Müssen eigentlich entsprechende Fuses oder Taktungen gesetzt werden, um den Timer-Interrupt zu betreiben? Der Controller wird auf einem STK500 in der Standard Einstellung betrieben (beides out-of-the-box). STK500 gibt den Takt vor (3,68 MHz).

    Link zum Original-Thread im Mikrocontroller.net forum: http://www.mikrocontroller.net/topic/174886

    Hoffe ihr könnt mir weiterhelfen!

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Aus dem anderen Thread:
    Hier mal der exakte Compiler-Aufruf:
    avr-gcc -g -Os -I/usr/lib/avr/include/ -funsigned-char
    -funsigned-bitfields -fpack-struct -fshort-enums -Wall
    -Wstrict-prototypes -Wa,-ahlms=program.lst -Wl,-Map=program.map,--cref
    -L../../lib program.c -o program
    1)
    Wo ist die mcu-Option?
    Das hier
    Code:
    #ifndef MCU             
    #define __AVR_ATmega8515__
    #endif
    ist kein adäquater Ersatz dafür (z.B. erfolgt das Linken dann nicht für den richtigen Controller).

    2)
    Was programmierst du dann in den Controller? Doch wohl nicht etwa jenes "program", oder?
    MfG
    Stefan

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31
    Zitat Zitat von sternst
    1)
    Wo ist die mcu-Option?
    Das hier
    Code:
    #ifndef MCU             
    #define __AVR_ATmega8515__
    #endif
    ist kein adäquater Ersatz dafür (z.B. erfolgt das Linken dann nicht für den richtigen Controller).
    Nie angegeben worden! Danke für den Hinweis, ich dachte die Definition reicht aus. Werde heute Abend mit MCU-Argument versuchen! Das klingt sehr plausibel, danke für den Hinweis!

    Zitat Zitat von sternst
    2)
    Was programmierst du dann in den Controller? Doch wohl nicht etwa jenes "program", oder?
    Der Code, den ich oben gepostet in diesem Thread gepostet habe, landet im Flash. Gibt es da ein Problem?

    Vielen Dank jedenfalls schonmal für den Hinweis mit dem MCU Argument. Das klingt sehr plausibel.

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von MrWhite
    Der Code, den ich oben gepostet in diesem Thread gepostet habe, landet im Flash.
    Welche Datei programmierst du in das Flash? Wenn es "program" ist, wird niemals irgendein Interrupt funktionieren.
    MfG
    Stefan

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31
    Zitat Zitat von sternst
    Zitat Zitat von MrWhite
    Der Code, den ich oben gepostet in diesem Thread gepostet habe, landet im Flash.
    Welche Datei programmierst du in das Flash? Wenn es "program" ist, wird niemals irgendein Interrupt funktionieren.
    Doch, die Datei namens program lade ich ins Flash. Also das Kompilat von program.c.

    Wieso kann das nicht funktionieren? Die Hauptschleifen funktionieren ja??!

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von MrWhite
    Wieso kann das nicht funktionieren?
    Weil das der ELF-Output des Compilers ist. Da ist eine Menge Zeug mit drin, was im Controller nichts zu suchen hat. Und nichts steht dann im Controller an der Adresse, wo es eigentlich stehen sollte (weshalb niemals irgendein Interrupt funktionieren wird). Das, was in den Controller zu programmieren ist, muss aus dieser ELF-Datei erst mal mittels objcopy extrahiert werden (*).
    Zitat Zitat von MrWhite
    Die Hauptschleifen funktionieren ja??!
    Ja, das ist die Crux an diesem ELF-Datei-Programmieren. Sehr simple Programme funktionieren meist trotzdem, weshalb derjenige dann denkt, er würde bei diesem Schritt keinen Fehler machen.

    PS: Warum benutzt du nicht einfach ein bekanntermaßen funktionierendes Makefile (z.B. von MFile generiert), dann hast du diese ganzen Probleme nicht. Denn in (*) lauert schon der nächste Fehler, den fast jeder macht, der das "von Hand" versucht.
    MfG
    Stefan

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31
    Mit diesen Informationen werde ich den Timer heute Abend hoffentlich zum Laufen bringen.

    Vielen Dank für die Hinweise!

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31
    Danke, du hast mir sehr geholfen.

    Der Overflow-Timer wird nun brav in der richtigen Frequenz aufgerufen.

    Allerdings habe ich ein neues Problem! Wenn ich im Interrupt-Handler auf globale Variablen zugreife, vergessen diese ihren Zustand beim nächsten Call. Die Variablen sind als volatile deklariert:

    Code:
    #ifndef MCU             
    #define __AVR_ATmega8515__
    #endif
    
    #ifndef F_CPU           
    #define F_CPU 4000000UL
    #endif
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/portpins.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    volatile uint8_t frequencyAdjustmentCounter = 0;
    volatile uint8_t frequencyAdjustmentThreshold = 14;
    
    ISR(TIMER0_OVF_vect)
    {
    	frequencyAdjustmentCounter++;  //ist nach durchlaufen des handlers wieder 0 ohne Port C zu schalten!
    	if(frequencyAdjustmentCounter == frequencyAdjustmentThreshold)
    	{
    		PORTC = ~PORTC;
    		frequencyAdjustmentCounter = 0;
    	}
    }
    
    int main()
    {
      DDRA   =  0xff;
      PORTA   =   0x0f;
     
      DDRC  =   0xff;
      PORTC   =   0x0f;
     
      TIMSK  |=  (1 << TOIE0);                //overflow timer einschalten
      TCCR0   =  (1 << CS02) | (0 << CS01) | (1 << CS00);  //prescaler auf 1024
     
      sei();     
     
      while(1)
      {
        PORTA = ~PORTA;
        _delay_ms(500);
      }
    }
    Die Variable "frequencyAdjustmentCounter" gilt komischerweise nur im Scope des Interrupt-Handlers!

    Den Compiler-Aufruf habe ich auf das äußerste simplifiziert, es wird praktisch nur das mmcu Argument angegeben.

    Woran kann das denn liegen?

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von MrWhite
    Den Compiler-Aufruf habe ich auf das äußerste simplifiziert, es wird praktisch nur das mmcu Argument angegeben.
    Du machst es also immer noch "von Hand", und ich weiß nicht, wie die Compiler-Kommandozeile denn nun genau aussieht. Und ich weiß auch nicht, wie du die zu programmierende Datei erzeugst und ob du dort den oben von mir angesprochenen Fehler machst (der durchaus der Grund für das aktuelle Problem sein kann). Du musst mir diese Dinge aber auch nicht unbedingt mitteilen, denn von mir wirst du erst wieder Hilfe bekommen, wenn du ein vernünftiges fertiges Makefile verwendest. Ich habe nämlich keine Lust, dir jetzt dieses "wie mache ich es selbst" bis ins letzte Detail zu erklären, einfach weil es Zeitverschwendung wäre.

    Also nimm ein fertiges Makefile (am besten generiert durch MFile), dann haben wir eine solide Ausgangsbasis, und wenn dann das Problem immer noch besteht, dann bin ich auch bereit mal einen intensiveren Blick auf den Code zu werfen.
    MfG
    Stefan

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    02.04.2010
    Beiträge
    31
    Entschuldigung bitte, ich werde in Zukunft MFile nutzen um ein Makefile zu erzeugen und falls die Probleme dann noch bestehen, mich wieder hier melden.

    Leider bin ich in der Arbeit und habe die genauen Aufrufe nicht zur Hand. Ein Makefile nutze ich schon, das habe ich aber von Hand geschrieben (hehe).

    Vielen Dank jedenfalls für deine Hilfsbereitschaft.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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