Forum: Mikrocontroller und Digitale Elektronik ATmega2560 resests after configuring timer


von Philipp (Gast)


Lesenswert?

Hallo zusammen,

ich versuche gerade einen Timer im CTC-Modus auf meinem ATmega2560 
(Arduino Mega 2560) ans Laufen zu kriegen. Allerdings startet der 
Control jedes Mal neu, wenn die Interrupts aktiviert wurden. Auf meinem 
ATmega644 hat der Code problemlos funktioniert und ich kann keine 
Unterschiede in den Datenblättern finden, was die Timerkonfiguration 
betrifft...
Hier ist mein Code:
1
#define F_CPU 16000000
2
3
#include <avr/interrupt.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
7
int main(void)
8
{
9
  // initialize timer
10
  TCCR0A = (1<<WGM02);           // enable CTC mode
11
  TCCR0B = (1<<CS00)|(1<<CS02);  // set prescaler to 1024
12
  OCR0A = 255;
13
  TIMSK0 |= (1<<OCIE0A);         // enable timer interrupt
14
  sei();
15
  
16
  while(1) ;
17
}
18
19
ISR(TIMER0_COMPA_vect) {
20
21
}
Hat jemand eine Idee was falsch sein könnte?

: Bearbeitet durch User
von Philipp (Gast)


Lesenswert?

kleine Korrektur:
TCCR0A = (1<<WGM01); (nicht WGM02, Problem besteht aber weiterhin)

von Karl H. (kbuchegg)


Lesenswert?

Irgendwelche Warnung zum Thema 'TIMER0_COMPA_vect'

Irgendwas in der Richtung .... does not appear to be correct vector name 
....?


Wenn der µC resettet, dann ist das ein Hinweis darauf, dass ein 
Interrupt freigegeben wurde (und auch auslöst), für den es keine ISR 
gibt. Das kann sein, weil es wirklich keine ISR dafür gibt, das kann 
aber auch sein, weil der Name falsch geschrieben ist. Leider sind die 
Namen bei unterschiedlichen Prozessoren da nicht ganz einheitlich, so 
dass man derartige Warnungen ernst nehmen muss.

: Bearbeitet durch User
von Holger S. (223rem)


Lesenswert?

Hey,

Du hast eine leere Interruptroutine!
Damit läuft der Atmega zum Prog anfang.
Schreib halt was rein. Oder:

EMPTY_INTERRUPT  (TIMER0_COMPA_vect)

Philipp schrieb:
> Auf meinem
> ATmega644 hat der Code problemlos funktioniert

mit Sicherheit nicht.

Gruß Holger...

von Karl H. (kbuchegg)


Lesenswert?

Holger Sch schrieb:
> Hey,
>
> Du hast eine leere Interruptroutine!
> Damit läuft der Atmega zum Prog anfang.

Ähm.
Nein. Das ist nicht der Grund.

Ob leer oder nicht, spielt keine Rolle.
Vorhanden muss er sein. Tun muss er nichts.

von Uwe (de0508)


Lesenswert?

Holger,

deine Aussage ist falsch!
"Du hast eine leere Interruptroutine!"

Die ISR ist nicht leer sie enthält nur ein reti !
Das ist ok !

von Philipp (Gast)


Lesenswert?

Ich hab die ISR im Post nur zur besseren Übersicht leer gelassen, aber 
ich denke auch nicht dass das ein Problem ist. Ich könnte auch etwas wie 
PORTC = 0xFF rein schreiben, ändert aber nichts.
Könnte das Problem etwas mit dem Arduino zu tun haben?

von Hilfe (Gast)


Lesenswert?

Der Code ist korrekt, läuft ja im Simu einwandfrei.
Setz mal was in die ISR, Portpin loggeln oder LED an/aus, damit du 
siehst ober überhaupt was läuft. Mit Multimeter oder Oszi Pin checken.

Woher weißt du, dass der uc resettet? Woher weisst du, ob er überhaupt 
läuft?

von Hilfe (Gast)


Lesenswert?

Läuft auf meinem Arduino Mega2560 Board ohne Probleme.
In der ISR lass ich PORTB toggeln. Die gelbe LED blinkt sichtbar.
Die .HEX hab ich mit dem XLoader aufgespielt.

von Philipp (Gast)


Lesenswert?

Okay, hier nochmal der vollständige Code, ist in der Tat verständlicher:
1
#define F_CPU 16000000
2
3
#include <avr/interrupt.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
7
int main(void)
8
{
9
  counter = 0;
10
  DDRC = 0xFF;
11
  
12
  PORTC = 0xFF;
13
  _delay_ms(500);
14
  PORTC = 0;
15
  _delay_ms(500);
16
  
17
  // initialize timer
18
  TCCR0A = (1<<WGM01);      // enable CTC mode
19
  TCCR0B = (1<<CS00)|(1<<CS02);  // set prescaler
20
  OCR0A = 255;
21
  TIMSK0 |= (1<<OCIE0A);      // enable timer interrupt
22
  sei();
23
  
24
    while(1) ;
25
}
26
27
ISR(TIMER0_COMPA_vect) {
28
  PORTC = 0xFF;
29
}
Wenn der Code korrekt ausgeführt wird, sollte eine Diode an PortC nur 
einmal am Anfang blinken und danach an bleiben. In der Praxis blinkt sie 
aber die Ganze Zeit (aber nur wenn ich die Interrupts aktiviere), woraus 
ich schließe dass der Controller resettet und die main() erneut 
ausführt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Philipp schrieb:
> Okay, hier nochmal der vollständige Code,

der Code compiliert nicht.
counter ist eine undefinierte Variable.

Das stärkt nicht unbedingt dein Renommee, wenn du als Hilfesuchender uns 
ungetesteten Code unterjubeln willst. Es sind oft die kleinen 
Unterlassungen der Sorgfaltspflicht die den Unterschied ausmachen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Womit compilierst du?
Bist du sicher, dass da ein Mega2560 bei mcu eingestellt ist?

In der Ausgabe (wie auch immer die bei dir aussieht), müsste eine 
Command Line aufscheinen, die ungefähr wie folgt aussieht:
1
avr-gcc.exe  -mmcu=atmega2560 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT ctc.o -MF dep/ctc.o.d  -c  ../ctc.c

wichtig ist das -mmcu

(das ist zb die Command Line, mit der AVR-Studio 4 dein Programm 
übersetzt)

: Bearbeitet durch User
von Philipp (Gast)


Lesenswert?

Sorry, hab die Zeile vergessen zu löschen.
Ich kompiliere mit avr-gcc in AtmelStudio 6, als uc ist der ATmega2560 
ausgewählt und in der Ausgabe wird Folgendes angezeigt:

-mmcu=atmega2560

"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 
GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-gcc.exe" 
-funsigned-char -funsigned-bitfields -DDEBUG  -O1 -ffunction-sections 
-fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall 
-mmcu=atmega2560 -c -std=gnu99 -MD -MP -MF "Test.d" -MT"Test.d" 
-MT"Test.o"   -o "Test.o" ".././Test.c"

Der ausgewählte uc sollte also der richtige sein. Ich habe den Code auch 
gerade nochmal auf meinem ATmega644 getestet (nach Anpassen des uc 
natürlich), da funktioniert alles...

von Philipp (Gast)


Lesenswert?

Könnte der Fehler an der Stromversorgung liegen? Ich versorge das Board 
im Moment über einen ISP-Programmierer mit 5V.

von Philipp (Gast)


Lesenswert?

Ich hab die Lösung gerade gefunden und poste sie hier nochmal für alle, 
die evtl mal das selbe Problem haben werden:
Die BOOTRST Fuse darf nicht programmiert sein (siehe auch 
Beitrag "BOOTRST Fuse ohne Bootloader"). Danach funktioniert alles 
einwandfrei.
Trotzdem danke für eure Hilfe.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Philipp schrieb:
> Die BOOTRST Fuse darf nicht programmiert sein

Es ist natürlich sinnvoll, sie nicht zu programmieren, wenn man keinen
Bootloader hat, aber auf die Interrupts sollte das keinen Einfluss
haben.  Die werden per IVSEL umgeschaltet.

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.