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
intmain(void)
8
{
9
// initialize timer
10
TCCR0A=(1<<WGM02);// enable CTC mode
11
TCCR0B=(1<<CS00)|(1<<CS02);// set prescaler to 1024
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.
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...
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.
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?
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?
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.
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
intmain(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.
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.
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:
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...
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.
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.