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


von Daniel P. (pfefferk)


Angehängte Dateien:

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!
1
#include <avr/io.h>                // include io definitions
2
#include <avr/interrupt.h>            // include interrupt definitions
3
#include <util/delay.h>              // delay functions
4
#include <avr/sleep.h>              // provides sleep instruction etc.
5
#include <stdbool.h>              // include bool definition
6
7
#define set_bit(var, bit)   ((var) |= (1 << (bit)))
8
#define clear_bit(var, bit)   ((var) &= (unsigned)~(1 << (bit)))
9
10
#define LED_DDR   DDRE
11
#define LED_PORT  PORTE
12
#define LED2    2
13
#define LED3    3
14
#define LED4    4
15
#define ALL_LEDS ((1<<LED2)|(1<<LED3)|(1<<LED4))
16
17
volatile uint8_t flag;
18
19
ISR( TIMER2_OVF_vect )
20
{
21
  flag = 1;
22
}
23
24
ISR(BADISR_vect)
25
{
26
  clear_bit(LED_PORT, LED2);
27
  clear_bit(TIMSK2, TOIE2);
28
}
29
30
31
int main(void) 
32
{
33
cli();
34
PRR0  |= (0xFF);              // Power Reduction Register0, shuts down: I2C, Timer0/1/2, PGA, SPI, USART0, ADC
35
clear_bit(PRR0, PRTIM2);          // enable Timer2
36
PRR1  |= (0xFF);              // shuts down: Transceiver, Timer3/4/5, USART1
37
PRR2  |= (0xFF);              // disables SRAM blocks
38
ASSR  &=~((1<<EXCLKAMR)|(1<<EXCLK));    // set clock source to external crystal AS2=1, EXCLK=0, EXCKLAMR=0
39
set_bit(ASSR, AS2);              // alternate clock source
40
TCCR2B   |= ((1<<CS22)|(1<<CS21)|(1<<CS20));  // set pre-scaler to longest possible (f_clk/1024)
41
set_bit(TIMSK2, TOIE2);            // enable overflow interrupt
42
sei();
43
while(1) {
44
    if (flag == 1){
45
      flag = 0;
46
      toggle_bit(LED_PORT, LED3);
47
    }
48
  }

Nochmals danke!

von Flo (Gast)


Lesenswert?

Wie erkennst du, dass der uC resettet wird?

von Daniel P. (pfefferk)


Lesenswert?

Ich habe den Code ein wenig gekürzt, mea culpa.

Ich flashe einmal die drei verfügbaren LEDs mit einem "Muster":
1
 cli();
2
  LED_DDR  = ALL_LEDS;                // enable LED pins as output
3
  LED_PORT &= ~ALL_LEDS;              // turn on LEDs (active low)
4
  for (loopvar=0; loopvar!=3; loopvar++){      // toggle LEDs
5
    _delay_ms(250);
6
    LED_PORT ^=ALL_LEDS;
7
  }
8
  _delay_ms(250);
9
  LED_PORT &= ~((1<<LED2)|(1<<LED4));
10
  _delay_ms(500);
11
  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!

von Flo (Gast)


Lesenswert?

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

von Daniel P. (pfefferk)


Angehängte Dateien:

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

von Flo (Gast)


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?

von holger (Gast)


Lesenswert?

ISR( TIMER2_OVF_vect )
{
  flag = 1;
//  clear_bit(LED_PORT, LED3);
}

Vieleicht hat dein LED Pin einen Kurzschluß? ;)

von Daniel P. (pfefferk)


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

von Flo (Gast)


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.

von Daniel P. (pfefferk)


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

von Stefan E. (sternst)


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?

von Daniel P. (pfefferk)


Angehängte Dateien:

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

von Kluchscheißernder N. (kluchscheisser)


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

von Daniel P. (pfefferk)


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!

von Alexander V. (avogra)


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

von Daniel P. (pfefferk)


Lesenswert?

Ist eine verdammt gute Idee. Leider steht im Makefile in Zeile 3
1
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

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von Karl H. (kbuchegg)


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.

von Daniel P. (pfefferk)


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.

von Werner B. (werner-b)


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.

von Werner B. (werner-b)


Lesenswert?

> internem/externem Timer-Takt

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

von Daniel P. (pfefferk)


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".
1
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!

von Karl H. (kbuchegg)


Lesenswert?

Daniel Pfefferkorn schrieb:

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

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

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

von Daniel P. (pfefferk)


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?
>
>>
1
>> PRR2  |= (0xFF);        // disables SRAM blocks
2
>>
>>
>> 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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.