www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR TIMER 2 overflow --> Reset


Autor: Daniel Pfefferkorn (pfefferk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend werte uC-Gemeinde!

Ich habe seit gestern ein Problem mit einem ATmega128RFA1 mit externem 
32 kHz-Quarz.

Mein Plan war es bei einem Überlauf des Timer2 (im asynchronen Modus) 
eine angeschlossene LED ab- bzw. wieder abzuschalten. Dazu habe ich den 
größtmöglichen Taktteiler (1024) gewählt, was bei 8-Bit-zähler und 
32,768 kHz-Quarz eine Interruptperiode von 8 s geben sollte.

Das Problem ist, dass der AVR nach 8 Sekunden zurückgesetzt wird
(Watchdog ist deaktiviert).

Ich weiß nicht mehr weiter, deswegen hier dieser Eintrag und nachfolgend 
mein Quellcode.

Vielen Dank im Voraus für Eure Bemühungen!
#include <avr/io.h>                // include io definitions
#include <avr/interrupt.h>            // include interrupt definitions
#include <util/delay.h>              // delay functions
#include <avr/sleep.h>              // provides sleep instruction etc.
#include <stdbool.h>              // include bool definition

#define set_bit(var, bit)   ((var) |= (1 << (bit)))
#define clear_bit(var, bit)   ((var) &= (unsigned)~(1 << (bit)))

#define LED_DDR   DDRE
#define LED_PORT  PORTE
#define LED2    2
#define LED3    3
#define LED4    4
#define ALL_LEDS ((1<<LED2)|(1<<LED3)|(1<<LED4))

volatile uint8_t flag;

ISR( TIMER2_OVF_vect )
{
  flag = 1;
}

ISR(BADISR_vect)
{
  clear_bit(LED_PORT, LED2);
  clear_bit(TIMSK2, TOIE2);
}


int main(void) 
{
cli();
PRR0  |= (0xFF);              // Power Reduction Register0, shuts down: I2C, Timer0/1/2, PGA, SPI, USART0, ADC
clear_bit(PRR0, PRTIM2);          // enable Timer2
PRR1  |= (0xFF);              // shuts down: Transceiver, Timer3/4/5, USART1
PRR2  |= (0xFF);              // disables SRAM blocks
ASSR  &=~((1<<EXCLKAMR)|(1<<EXCLK));    // set clock source to external crystal AS2=1, EXCLK=0, EXCKLAMR=0
set_bit(ASSR, AS2);              // alternate clock source
TCCR2B   |= ((1<<CS22)|(1<<CS21)|(1<<CS20));  // set pre-scaler to longest possible (f_clk/1024)
set_bit(TIMSK2, TOIE2);            // enable overflow interrupt
sei();
while(1) {
    if (flag == 1){
      flag = 0;
      toggle_bit(LED_PORT, LED3);
    }
  }

Nochmals danke!

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie erkennst du, dass der uC resettet wird?

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den Code ein wenig gekürzt, mea culpa.

Ich flashe einmal die drei verfügbaren LEDs mit einem "Muster":
 cli();
  LED_DDR  = ALL_LEDS;                // enable LED pins as output
  LED_PORT &= ~ALL_LEDS;              // turn on LEDs (active low)
  for (loopvar=0; loopvar!=3; loopvar++){      // toggle LEDs
    _delay_ms(250);
    LED_PORT ^=ALL_LEDS;
  }
  _delay_ms(250);
  LED_PORT &= ~((1<<LED2)|(1<<LED4));
  _delay_ms(500);
  LED_PORT |= ALL_LEDS;                // Turn off LEDs for measurement

Wenn ich den Interrupt maskiere, kommt es nicht zum Reset.
In der Assemblerdatei sind die Einsprungadressen auch korrekt. Falls da 
Interesse besteht, einfach melden.

Danke!

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du mal den ganzen Code einfach als Anhang hochladen bitte?
Ist tierisch mühsam, aus den Codeschnipseln was zu erkennen ;D

Autor: Daniel Pfefferkorn (pfefferk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die Idee war, dass die Verkürzung hilfreich sein könnte und auf das 
Problem fokussiert.

Vielen Dank für die Hilfe!
Daniel

So, damit ich ausreichen Text habe, hier noch ein paar Zeilen unsinniges 
BLABLA :(

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, Code ist da, jetzt fehlt nur noch die Fehlerbeschreibung ;D

Also, der uC startet und gibt das Muster aus, danach verweilt er in der 
while-Schleife (was ein Wortspiel xD), und sollte alle 8 s seine LED3 
toggeln.
Was funktioniert jetzt genau nicht an dem Programm, bzw. wo hängt er?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR( TIMER2_OVF_vect )
{
  flag = 1;
//  clear_bit(LED_PORT, LED3);
}

Vieleicht hat dein LED Pin einen Kurzschluß? ;)

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> So, Code ist da, jetzt fehlt nur noch die Fehlerbeschreibung ;D
>
> Also, der uC startet und gibt das Muster aus, danach verweilt er in der
> while-Schleife (was ein Wortspiel xD), und sollte alle 8 s seine LED3
> toggeln.
> Was funktioniert jetzt genau nicht an dem Programm, bzw. wo hängt er?

Exakt. Aber nach 8 s erfolgt ein Reset und er präsentiert wieder das 
"Startmuster".

@Holger: Dass das auskommentiert ist, ist schon in Ordnung. Einen 
Kurzschluss kann ich bei der Beschaltung nicht erzeugen (LED hängt mit 
Vorwiderstand von Vdd kommend am PIN). Um die jetzt zum Leuchten zu 
bringen, muss ich den als Ausgang definierten PIN gegen Masse ziehen 
(clear), zum Abschalten intern gegen Vdd (set).

Vielen Dank für die Hilfe!
Daniel

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Haste grad das Datenblatt von dem Controller da? Find grad auf die 
schnelle nur die Preliminary.

Ganz sicher, dass die Einsprungstelle stimmt? Weil sonst könnt ich mir 
grad nichts denken, was den Controller wieder resettet.

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Augenblick gibt es nur das Preliminary, die nächste Revision ist noch 
im "Legal Review".

In der "iomega128rfa1.h" (avr/...) ist der Vektor aber identisch zu dem 
im Datenblatt angegebenen (15). Eben deswegen kann ich es mir auch nicht 
erklären.

Vielleicht fällt ja jemandem noch etwas ein.

Daniel

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die ISR hat den richtigen Namen, und der Vector wird richtig 
eingetragen, aber dennoch gibt es beim Interrupt einen Soft-Reset. Dann 
lautet die nächste Frage: wie compilierst du und was (welche Datei) 
programmierst du in den Chip?

Autor: Daniel Pfefferkorn (pfefferk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich kompiliere mit der WinAVR-20100110 beigefügten Version von avr-gcc 
(4.3.3) und flashe mit der erzeugten HEX-Datei. Ich habe das Ganze aber 
auch schon mit AVRStudio mit gleichem Ergebnis nachvollzogen. (Neues 
Projekt -> nur die zwei Quelltextdateien eingefügt -> Plattform 
eingestellt -> Build -> Flash von Datei)

Ich verstehe einfach nicht was da schief läuft. Anbei das verwendete 
Makefile.

Danke für Eure Bemühungen!
Daniel

Autor: Kluchscheißernder Nixwisser (kluchscheisser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel Pfefferkorn schrieb:
> Ich kompiliere mit der WinAVR-20100110 beigefügten Version von avr-gcc
> (4.3.3)

Das mag ja sein, gelegentlich werden aber Dateien aus einem andeen 
Ordner als vermutet vearbeitet. Das passiert besonders, wenn man 
Projekte kopiert hat. Schau Dir mal die Path-Angaben in der 
Projekt-Datei an.

> und flashe mit der erzeugten HEX-Datei.

Das mag auch sein, ist jedoch gelegentlich auch ein Irrtum. Also lieber 
nochmal genau hinsehen.

> Ich habe das Ganze aber
> auch schon mit AVRStudio mit gleichem Ergebnis nachvollzogen. (Neues
> Projekt -> nur die zwei Quelltextdateien eingefügt -> Plattform
> eingestellt -> Build -> Flash von Datei)
>
> Ich verstehe einfach nicht was da schief läuft. Anbei das verwendete
> Makefile.
>
> Danke für Eure Bemühungen!
> Daniel

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann wenn ich den Pre-Scaler anders wähle den|das Reset auch 
schneller herbeiführen, d.h. es wird schon die richtige Datei geflasht. 
Ich verwende dazu einen JTAGICE mkII mit neuester Firmware.

Das andere Dateien verarbeitet werden, kann eigentlich auch nicht sein, 
weil ich (wie ich auch geschrieben habe) das Projekt nicht kopiere, 
sondern gänzlich neu anlege und nur die beiden Quelltextdateien 
hinzufüge. Nicht mehr, nicht weniger.

Danke für Eure Ideen!

Autor: Alexander v. Grafenstein (avogra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich programmier eigentlich nur in Assembler, könnt also grad Käse 
erzählen. Mir is aufgefallen, dass nirgends der Prozessor-Typ angegeben 
wird. Das mach ich immer gleich als erstes. Falls er für den falschen µC 
compiliert, könnten die ISR-Adressen anders sein und der Rest 
funktioniert nur zufällig. Aber dann könntest wahrscheinlich gar nicht 
flashen. Nur so ne Idee :)

Gruß, Alex

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist eine verdammt gute Idee. Leider steht im Makefile in Zeile 3
MCU = atmega128rfa1

Ich habe festgestellt, dass es sich nicht nur auf den Overflow-Interrupt 
bezieht, sondern auch auf die Compare-Match-Interrupts.

Wenn ich z.B. den intern getakteten Timer4 nutze, funktioniert alles wie 
erwartet. Aber ich brauche Timer2, weil ich ihn durch einen externen 32 
kHz-Quarz takten lassen will/muss.

EDIT:

Wenn ich den Timer2 mit dem internen Systemtakt laufen lasse, wird die 
ISR wie erwartet ausgeführt und es kommt nicht zum "Reset des Todes".
Es muss also etwas mit der "externen Clock" zu tun haben.

Hat da jemand eine Idee?

Viele Grüße,
Daniel

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Mach doch mal ein Assembler-Listing von deinem Programm. Da sieht man 
u.U. mehr.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel Pfefferkorn schrieb:

> Wenn ich den Timer2 mit dem internen Systemtakt laufen lasse, wird die
> ISR wie erwartet ausgeführt und es kommt nicht zum "Reset des Todes".
> Es muss also etwas mit der "externen Clock" zu tun haben.
>
> Hat da jemand eine Idee?

Den internen Takt wollte ich dir auch vorschlagen, aber das hast du 
selbst schon probiert.
Bleibt mir nur noch: Abspecken!
Alles rauswerfen, was nicht wirklich unmittelbar mit dem Timer zu tun 
hat.
Zb. Watchdog, das ganze Power Reduction Gedöns, in einem deiner 
Kommentare hab ich auch was von irgendwelchen UART Einstellungen 
gelesen, etc.

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erstmal ein UPDATE:

Es läuft jetzt auch mit externem Timer-Takt! YEAH!

Interessanterweise konnte ich noch keinen entscheidenden Unterschied im 
Quellcode entdecken, aber ich mache gerade ein "diff" mit einer älteren 
Version (Versionierungssysteme sind Dein Freund!).

Es freut mich schon mal sehr.

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A) Sind die Vektoren evtl. auf die Bootsection umgestellt?
B) In den "ISR(BADISR_vect)" am Ende ein "while(1);" Sonst sieht man 
doch nichts.

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> internem/externem Timer-Takt

Das bringt mich auf Fuses. War vorher evtl. eine unzulässige/reservierte 
Fuse Kombination programmiert?

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werner B. schrieb:
> A) Sind die Vektoren evtl. auf die Bootsection umgestellt?

Ich habe die Lösung gefunden!
Es ist ein Einzeiler und sowohl Werner B. als auch Karl heinz Buchegger 
hatten "den richtigen Riecher".
PRR2  |= (0xFF);        // disables SRAM blocks

Ich habe einfach alle SRAM-Blöcke abgeschaltet. Keine so gute Idee. :D 
Das war/ist sozusagen ein Überbleibsel aus den Energieaufnahmetests.

Wenn ich alle bis auf SRAM-Block0 geht es noch.

> B) In den "ISR(BADISR_vect)" am Ende ein "while(1);" Sonst sieht man
> doch nichts.
Volle Zustimmung!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel Pfefferkorn schrieb:

Wenn es sich nicht in 10 oder weniger Worten beschreiben lässt, dann 
lass es. Aber: Was macht das eigentlich?

>
> PRR2  |= (0xFF);        // disables SRAM blocks
> 
>
> Ich habe einfach alle SRAM-Blöcke abgeschaltet.

Lass mich raten: Du hattest dann kein SRAM für den Stack mehr?

Autor: Daniel Pfefferkorn (pfefferk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Wenn es sich nicht in 10 oder weniger Worten beschreiben lässt, dann
> lass es. Aber: Was macht das eigentlich?
>
>>
>> PRR2  |= (0xFF);        // disables SRAM blocks
>> 
>>
>> Ich habe einfach alle SRAM-Blöcke abgeschaltet.
>
> Lass mich raten: Du hattest dann kein SRAM für den Stack mehr?

Ganz genau diese Zeile war das Problem! Mit aktiviertem SRAM-Block0 
läuft's wie geschmiert. :D

Daniel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.