Timer funktioniert nicht richtig wenn etwas in mainwhile gemacht wird

Gast #2138669
Lesenswert?

Hi Leute,

hat jemand ein paar tips woran es liegen könnte, dass mein Timer nicht 
mehr richtig funktioniert sobald ich in die mainwhile schleife einen 
ausgang toogeln lasse?

Könnte eventuell daran liegen, dass in meinem Timer Interrupt routine 
zuviel drin steht. Aber ich möchte gerne verstehen warum dieses 
Verhalten auftritt. Ich weiss, es ist nicht ganz so toll so viel da 
reinzuschreiben, aber was passiert da genau?

Es geht darum die Syncs eines FBAS Signals zu erzeugen.
Angehängte Dateien:
Gast #2138680
Lesenswert?

Das toogeln eines anderen Ausgangs, welches in der Timer Interrupt 
Routine ausgelöst wird funktioniert nicht. Scheint als würde der Timer 
gar nicht mehr ausgelöst.

Für was ist den eigentlich das hier
(TIFR |= (_BV(OCF1A)))

Ich weiss das man das ab und zu machen muss aber nicht warum.

Hat das was damit zu tun? Wenn ich das mit ans ende der Interrupt 
Routine packe funktioniert es aber trotzdem nicht.
Gast #2138697
Lesenswert?

Ich habe den Eindruck, das die Komplexität des Codes nicht zu den Fragen 
passt.
Das sind Grundlagenfragen die entweder im Datenblatt geklärt werden bzw. 
bei den ersten grundlegenden Experimenten mit Timerinterrupts 
auftauchen.
Wenn das stimmt, dann musst Du Dir erst noch eine Reihe von 
Grundkenntnissen und Erfahrungen aneignen, ehe Du solche Probleme 
angehen und die entsprechenden Antworten sinnvoll in Aktionen (also 
Programme bzw. Änderungen daran) umsetzen kannst.
Gast #2138780
Lesenswert?

> Für was ist den eigentlich das hier
> (TIFR |= (_BV(OCF1A)))
> Ich weiss das man das ab und zu machen muss aber nicht warum.

Die Zeile ist falsch.

Ein Interruptflag kann man löschen und dann wird der Interrupt nicht 
mehr ausgeführt. Das Löschen geht beim AVR in dem man eine 1 an die 
Bitposition des Interruptflags schreibt. Eine VerODERung ist da 
tückisch: andere gesetzte Interruptflags werden mitgelöscht

Falsch
  TIFR |= (_BV(OCF1A));

Bsp:
TIFR sei 0b00000011

Bit0 soll gelöscht werden: TIFR |= (_BV(0))
Was passiert?
TIFR = 0b00000011 | 0b00000001
TIFR = 0b00000011
d.h. Bit0 und Bit1 werden mit 1 beschrieben. Ein vorhandenes 
Interruptflag auf Bit1 wird ebenfalls gelöscht

Richtig
  TIFR = (_BV(OCF1A)));

TIFR sei 0b00000011
Bit0 soll gelöscht werden: TIFR = (_BV(0))
Was passiert?
TIFR = 0b00000001
d.h. nur Bit0 wird mit 1 beschrieben. Ein vorhandenes Interruptflag 
auf Bit1 wird nicht gelöscht, weil es nicht mit einer 1 beschrieben 
wird
TIFR ist nachher 0b00000010
Gast #2139288
Lesenswert?

Ok das mit dem volatile ist klar, das habe ich vergessen! Trotzdem 
funktioniert es leider nicht. Habe nun auch das Bit in TIFR anders 
gesetzt, bzw gelöscht.

Ich habe mal irgendwo gelesen, dass man dieses Flag löschen in die 
Interrupt Routine reinschreiben kann oder sollte. Aber verstehe nicht 
warum? Wird doch eh gelöscht wenn die Routine fertig ist oder?

Das Problem mit dem Toogeln in der mainwhile was mein Timer 
durcheinanderbringt ist nun erstmal nebensächlich. Ich lasse ja am 
Anfang der Interrupt Routine einen Ausgang umschalten und nun auch noch 
am Ende, um praktisch zu messen wie lange die Interruptroutine 
durchläuft. Ich habe die Assembler Befehle für mehrere mögliche 
durchläufe gezählt und bin bei einer Variante z.B. auf 120 Befehle 
gekommen. Angenommen jeder Befehl benötigt einen Takt, währen das bei 
16MHz 7,5µs. Schau ich mir jedoch meinen Ausgang an, welcher mir das 
Ende der Routine anzeigt, ist dieser ungefähr bei 55µs. Also selbst wenn 
der ein oder andere Assembler Befehl mehr als einen Takt braucht, ist 
das nicht schlüssig.

Wie kann es sein, dass eine Interruptroutine doch noch irgendwie länger 
braucht? Habe ich irgendetwas vergessen zu beachten? Wie viele Takte 
werden benötigt, um nach einem match mit den push's am Anfang der 
Interrupt routine zu beginnen?

Im Datenblatt konnte ich das nicht finden. Ich fand nur, dass das OC... 
Flag einen Takt nach dem match gesetzt wird.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren