Forum: Compiler & IDEs TIMER0_OVF_vect wird nicht angesprungen


von Frank L. (franklink)


Lesenswert?

Hallo Zusammen,

ich bin am Verzweifeln. Meine Routine für TIMER0_OVF_vect wird nicht 
angesprungen. Warum keine Ahnung. Aus meiner Sicht sind alle IRs 
freigeschaltet und korrekt initialisiert.

Könnte sich mal jemand den entsprechenden Code ansehen.

Im Anhang der gesamte Code als ZIP-Archiv.

Die Initialisierung befindet sich initTimer() im File main.c

Danke für jeden Tipp.

Gruß
Frank

von Frank L. (franklink)


Angehängte Dateien:

Lesenswert?

und hier nochmal der Code.

von MWS (Gast)


Lesenswert?

Das hier schaut komisch aus:

TIMSK  = 1<<TOIE0^1<<TOIE1^1<<TOIE2;

Dachte man würde so schreiben:

TIMSK = (1 << TOIE0) | (1 << TOIE1) | (1 << TOIE2)

Schau doch mal im Disassembler, was da der Compiler so erzeugt.
Aber ich schreib in Bascom, könnte hier also die Lizenz haben falsch zu 
liegen.

von Frank L. (franklink)


Lesenswert?

Hallo,
ich habe gestern Abend noch ein wenig experimentiert.

Das Ergebnis ist folgendes:

Mit dieser Initialisierung ist die Anwendung letzte Woche noch gelaufen. 
Seit Montag nicht mehr. Auch wenn ich alle Änderungen die ich seit dem 
gemacht habe, zurücknehmen, wird der TIMER0_OVF_vect nicht angesprungen.
1
void initTimer( void )
2
{
3
  TCCR0  = 0;
4
  TCCR0  = 1<<CS02;                 
5
6
  TCCR1A = 1<<CS10;                 
7
  TCCR1B = 1<<CS10;                 
8
9
  TCCR2  = 0;
10
  TCCR2  = 1<<CS11;                 
11
12
   TIMSK  = 1<<TOIE0^1<<TOIE1^1<<TOIE2;  // enable timer interrupt
13
}

Ändere ich die Parameter auf:
1
void initTimer( void )
2
{
3
  TCCR0  = 0;
4
  TCCR0  = 1<<CS02;                 
5
6
  TCCR1A = 0;
7
  TCCR1B = 1<<CS10;                 
8
9
  TCCR2  = 0;
10
  TCCR2  = 1<<CS11;                 
11
12
   TIMSK  = 1<<TOIE0^1<<TOIE1^1<<TOIE2;  // enable timer interrupt
13
}

wird der TIMER0_OVF_vect angesprungen. Allerdings ist dann der Aufruf 
des Vektors für TIMER1_OFV_vect zu langsam und damit läuft meine gesamte 
PWM nicht mehr vernüftig.

Genauso wird der Vektor angesprungen, wenn ich TOIE1 vollständig 
entferne.

Für mich stellt sich jetzt die Frage, was genau ist falsch...

Gruß
Frank

von Johannes M. (johnny-m)


Lesenswert?

> TCCR1A = 1<<CS10;
> TCCR1B = 1<<CS10;
Was das soll, weißt wohl sowieso nur Du selbst...

Abgesehen davon: MWS hat im Prinzip Recht: EXOR (^) ist da unsinnig. 
Mach es mit OR (|) und klammere die Teilausdrücke (v.a. wegen der 
Übersicht).

von Johannes M. (johnny-m)


Lesenswert?

Und noch ein kleiner Tip am Rande:
Bei Funktionsprototypen ist extern flüssiger als Wasser...

von Karl H. (kbuchegg)


Lesenswert?

Johannes M. wrote:

> Abgesehen davon: MWS hat im Prinzip Recht: EXOR (^) ist da unsinnig.

Ungewohnt, ja.
Aber da die Konstanten alle andere Werte haben, ist das auch nicht 
unbedingt falsch. Das kann es also nicht sein.

von Lutz (Gast)


Lesenswert?

TCCR0  = 0;
TCCR0  = 1<<CS02;

TCCR2  = 0;
TCCR2  = 1<<CS11;

Und da Du mit "=" arbeitest, kannst Du Dir das vorherige "=0" auch 
sparen.

von Frank L. (franklink)


Lesenswert?

Hallo,
erstmal Danke für die Antworten.

Ich habe das Konstrukt auch schon in der üblichen Schreibweise 
verwendet.
1
void initTimer( void )
2
{
3
  TCCR0  = 0;
4
  TCCR0  = 1<<CS02;                 
5
6
  TCCR1A = 0;
7
  TCCR1B = 1<<CS10;                 
8
9
  TCCR2  = 0;
10
  TCCR2  = 1<<CS11;                 
11
12
   TIMSK  = (1<<TOIE0)|(1<<TOIE1)|(1<<TOIE2);  // enable timer interrupt
13
}

bringt keinen Unterschied!

Fakt ist, setzte ich TCCR1A = 0 funktionierts! Setzte ich TCCR1A = 
1<<CS10 laufen alle anderen Interuptaufrufe mit Ausnahme von 
TIMER0_OVF_vect  korrekt und in der von mir erwarteten Geschwindigkeit.

Setzte ich TCCR1A = 0 laufen alle Interupts nur Timer1 zu langsam.

Da ich nicht wirklich der Krack in Mikrocontroller und C bin, bin ich 
mit meinem Latein am Ende.

TCCR0 = 0 und TCCR2 = 0 sind mit Sicherheit überflüssige Angaben, da sie 
aber auch nicht wehtun, habe ich sie noch gelassen. Werden allerdings 
irgendwann wenn der Code sauber funktioniert entfernt. Wobei ich auch 
hier sehr merkwürde Effekte hatte. Die aber damit zusammen hängen 
können, dass irgendetwas anderes falsch ist.

@Johannes
Setzte ich TCCR1A und TCCR1B nicht funktioniert der Timer1 überhaupt 
nicht. Mir ist im Augenblick keine andere Alternative bekannt, den 
Timer1 korrekt zu initialisieren.

Gruß
Frank

von Werner B. (werner-b)


Lesenswert?

Da niemand (außer dir) weiss welcher Prozessor, kann auch niemand prüfen 
in welchem Modus du den Timer betreibst, respektive warum es mit
1
  TCCR1A = 0;
2
  TCCR1B = 1<<CS10;
funtioniert, und mit
1
  TCCR1A = 1<<CS10;
2
  TCCR1B = 1<<CS10;
nicht.
Abgesehe davon kann es nur in einem der beiden Register ein Bit mit dem 
Namen CS10 geben.
Alles etwas Konfus.

Werner

von Johannes M. (johnny-m)


Lesenswert?

Werner B. wrote:
> Abgesehe davon kann es nur in einem der beiden Register ein Bit mit dem
> Namen CS10 geben.
Das war das, was ich oben meinte...

von Frank L. (franklink)


Lesenswert?

Hi Werner,
da hast Du verdammt Recht. Sorry, mein Controller ist ein ATMEGA8.

Ich denke, ich habe den Fehler nach dem Studium der Unterlagen auch 
gefunden.

CS10 für TCCR1A ist schlicht weg falsch. Hier ist TCCR1A = 0 korrekt.

Zusätzlich setzte ich im TIMER0_OVF_vect den TCNT0 und nicht den TCNT1. 
Copy und Paste ohne nachdenken :-((, deshalb hat es letzte Woche auch 
noch alles korrekt funktioniert.

Gruß
Frank

von Lowtzow .. (lowtzow)


Lesenswert?

1
>   TCCR1A = 1<<CS10;
2
>   TCCR1B = 1<<CS10;
3
>

hallo

was hier passiert kann ich dir sagen (hatte selber mal das problem)

1. variante
1
>   TCCR1A = 1<<0;
2
>   TCCR1B = 1<<0;
3
>

2.variante
1
>   TCCR1A = 1<<WGM10;
2
>   TCCR1B = 1<<CS10;
3
>

beide varianten sind gleichwertig mit deiner variante!
wieso? die bitbezeichnung (CS10)steht für die bitnummer(0).
wenn du CS10 woanders verwendest wird es als 0 interpretiert was aber 
jenach register eine andere funktion auslöst.

mfg

von Frank Link (Gast)


Lesenswert?

Hallo Alex Alex,
dank für die Zusammenfassung, ich hatte das als Abschluss für den Thread 
komplett vergessen zu schreiben.

Gruß
Frank

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.