Forum: Mikrocontroller und Digitale Elektronik Interrupthandling


von ATMEGA644V (Gast)


Lesenswert?

Hallo Zusammen.

Ich habe bei meinem ATMEGA644V zwei Interrupts.

Timer2-Compare Interrupt (alle ca. 200µs)
Timer0-Overflow Interrupt (ca. jede us)

Die ISR für den Timer2-Compare Interrupt toggelt mir testweise einen 
Pin.
Die ISR fr Timer0 ist leer.

Wenn die Timer0 ISR auskommentiere (also den Zähler nichtmal laufen 
lasse), dann habe ich einen schönen Abstand von meinen 200µs. Wenn aber 
meine Andere ISR auch läuft, dann stört sie meine 200µs ISR OBWOHL laut 
Datenblatt der Timer2-Compare Interrupt eine höhere Priorität als die 
des anderen Timers hat.


Woran kann das noch liegen?

Gruss

von Dietrich L. (dietrichl)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> Timer0-Overflow Interrupt (ca. jede us)

Mit welchem Takt läuft denn der µC?

Ich vermute mal, dass die Abarbeitung des Interrupts (auch wenn die ISR 
leer ist) mehr als 1µs braucht. Das kann dann nicht funktionieren.

Gruß Dietrich

von ATMEGA644V (Gast)


Lesenswert?

20MHZ.. ich habe im Netz versucht zu finden, wie lange so ein Aufruf 
dauert habe aber keine (zuverlässige) Aussage gefunden.

von Peter II (Gast)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> dann stört sie meine 200µs ISR OBWOHL laut
> Datenblatt der Timer2-Compare Interrupt eine höhere Priorität als die
> des anderen Timers hat.

genau lesen! Es gibt keine wirklichen Priorität bei diesem µC. Das was 
du meinst tritt nur ein wenn beide ISR gleichzeitg angeforder werden. 
Wenn vorher schone eine ISR läuft wird sie nicht unterbrochen.

von ATMEGA644V (Gast)


Lesenswert?

EDIT: Das Problem besteht allerdings auch, wenn der Interrupt ca. jede 
Millisekunde ausgeführt wird.

von (prx) A. K. (prx)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> Datenblatt der Timer2-Compare Interrupt eine höhere Priorität als die
> des anderen Timers hat.

Ein höher priorisierter Interrupt unterbricht bei AVRs keinen niedriger 
priorisierten Interrupt. Die Prio ist nur relevant, wenn beide 
Interrupts praktisch gleichzeitig eintreffen.

von ATMEGA644V (Gast)


Lesenswert?

A. K. schrieb:
> Ein höher priorisierter Interrupt unterbricht bei AVRs keinen niedriger
> priorisierten Interrupt.

NICHT?
Das wusste ich nicht..

Naja, ich denke der Interruptaufruf wird wohl kaum 1µs dauern oder doch?

von ATMEGA644V (Gast)


Lesenswert?

Die Abweichung beträgt nämlich ca. 5µs.

von Falk B. (falk)


Lesenswert?

@ATMEGA644V (Gast)

>Timer2-Compare Interrupt (alle ca. 200µs)

Geht noch, 5kHz.

>Timer0-Overflow Interrupt (ca. jede us)

Geht's noch? Das ist 1 MHz! Mit welchem Takt läuft dein AVR?

>Wenn die Timer0 ISR auskommentiere (also den Zähler nichtmal laufen
>lasse), dann habe ich einen schönen Abstand von meinen 200µs.

Gut.

Siehe Interrupt. Der AVR hat keine echten Prioritäten, sprich 
verschachtelte Interrupts. Aber 1 MHz Intteruptfrequenz ist schlicht 
Unsinn. 100kHz vielleicht, aber mehr kaum.

>20MHZ.. ich habe im Netz versucht zu finden, wie lange so ein Aufruf
>dauert habe aber keine (zuverlässige) Aussage gefunden.

Hast du mal im DATENBLATT gesucht? Stichwort interrupt response time. 
Eine ISR wird in 4 Takten angesprungen, der RETI dauert ebenfalls 4 
Takte. Das ist das absolute Minimum, wenn man mit Assebler arbeitet. In 
C kommt da noch zusätzliche Zeit für das Sichern von Registern hinzu.

Also wie immer. RTFM!

von (prx) A. K. (prx)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> Timer0-Overflow Interrupt (ca. jede us)

Einen Interrupt pro Mikrosekunde? Bisschen krass.

von Dietrich L. (dietrichl)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115281:
> EDIT: Das Problem besteht allerdings auch, wenn der Interrupt ca. jede
> Millisekunde ausgeführt wird.

Der Timer0-Interrupt? Wenn das so ist, wird es vielleicht an einem 
Fehler im Programm liegen?

Zeig mal den Code.

ATMEGA644V schrieb im Beitrag #3115288:
> Naja, ich denke der Interruptaufruf wird wohl kaum 1µs dauern oder doch?

Dann rechne doch mal die Befehle zusammen, die abgearbeitet werden. Wenn 
Du in C programmierst, findest Du das Compilierergebnis im .lss - File.

Gruß Dietrich

von Rolf M. (rmagnus)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> Timer0-Overflow Interrupt (ca. jede us)

Das ist aber sehr viel. Da hat der Prozessor nur 20 Taktzyklen Zeit 
zwischen zwei Interrupts.

ATMEGA644V schrieb im Beitrag #3115279:
> 20MHZ.. ich habe im Netz versucht zu finden, wie lange so ein Aufruf
> dauert habe aber keine (zuverlässige) Aussage gefunden.

Eine leere ISR (mit Sicherung der Flags) dürfte so ca. auf 12-15 
Taktzyklen kommen, je nach dem, wann genau der Interrupt eintritt, 
sofern der Compiler nicht noch irgendwelche zusätzlichen Instruktionen 
eingefügt hat.
Also ist der Prozessor schon 2/3 seiner Zeit nur mit der leeren ISR 
beschäftigt.

von Peter D. (peda)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115268:
> Die ISR für den Timer2-Compare Interrupt toggelt mir testweise einen
> Pin.

Dann nimmste eben Pin PD6 oder PD7 und läßt ihn per Hardware togglen. 
Das ist dann Zyklus genau.

Grob kann man für kleine Interrupts 50..100 Zyklen Bearbeitungszeit 
rechnen (AVR-GCC).

von ATMEGA644V (Gast)


Lesenswert?

1
void main() 
2
{
3
  TCCR0B |=  (1<<CS00);    
4
  TIMSK0 |= (1<< TOIE0);  
5
6
  TCCR1B |= (1<<CS10) | (1<<WGM12); 
7
  TIMSK1 |= (1<<OCIE1A);                         
8
9
10
  for(;;)
11
  {
12
  }
13
14
}
15
16
ISR (TIMER1_COMPA_vect) //Interrupt Routine für Ausgabe
17
{ 
18
  pulsePIN();
19
}
20
21
ISR (TIMER0_OVF_vect)   //Interrupt Routine für's Zählen
22
{
23
  
24
}

Das wäre mein Code..

Dietrich L. schrieb:
> Du in C programmierst, findest Du das Compilierergebnis im .lss - File.

Hmm.. ich finde 28(!) Befehle? Ist doch ein wenig viel für so einen 
popeligen Aufruf, nicht?

von Rolf M. (rmagnus)


Lesenswert?

Rolf Magnus schrieb:
> Eine leere ISR (mit Sicherung der Flags) dürfte so ca. auf 12-15
> Taktzyklen kommen, je nach dem, wann genau der Interrupt eintritt,

Gemeint war ohne Sicherung der Flags/Register. Die braucht nochmal 10 
Taktzyklen (oder mehr, sobald die ISR nicht mehr leer ist).

von ATMEGA644V (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Dann nimmste eben Pin PD6 oder PD7 und läßt ihn per Hardware togglen.
> Das ist dann Zyklus genau.

Lustigerweise funktioniert das peinlich genau.
Jetzt bin ich doch ein wenig verblüfft.. woran kann das liegen?

von ATMEGA644V (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Also ist der Prozessor schon 2/3 seiner Zeit nur mit der leeren ISR
> beschäftigt.

Das macht echt nicht wirklich Sinn.. ich muss mir da noch was überlegen.
Wenn ich also jetzt noch einen Prescaler reinmache und die ISR alle 8µs 
aufgerufen wird, dann habe ich ca. 7.2µs Zeit?

Das würde noch gehen schätze ich mal..

von Peter D. (peda)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115314:
> Hmm.. ich finde 28(!) Befehle? Ist doch ein wenig viel für so einen
> popeligen Aufruf, nicht?

Nö, ist schließlich ein RISC.
Zeig dochmal das compilierbare Programm (als Anhang!).

von Rolf M. (rmagnus)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115314:
> Das wäre mein Code..

Das läuft bei mir aber so nicht durch den Compiler. Da fehlen die Header 
und die Funktion pulsePIN().

ATMEGA644V schrieb im Beitrag #3115314:
> Dietrich L. schrieb:
>> Du in C programmierst, findest Du das Compilierergebnis im .lss - File.
>
> Hmm.. ich finde 28(!) Befehle? Ist doch ein wenig viel für so einen
> popeligen Aufruf, nicht?

Welches Optimierungslevel hast du denn eingestellt? Und welchen Aufruf? 
pulsePIN()? Falls der Compiler den Aufruf nicht inilinen kann, ist das 
sehr schlecht. Funktionsaufrufe ohne Inlining aus ISRs heraus sind 
ziemlich teuer. Da der Compiler nicht weiß, welche Register innerhalb 
der Funktion benutzt werden, ist er gezwungen, vor dem Aufruf alle zu 
sichern und danach wiederherzustellen.

ATMEGA644V schrieb im Beitrag #3115336:
> Das macht echt nicht wirklich Sinn.. ich muss mir da noch was überlegen.
> Wenn ich also jetzt noch einen Prescaler reinmache und die ISR alle 8µs
> aufgerufen wird, dann habe ich ca. 7.2µs Zeit?

Nunja, ich nehme mal an, daß deine ISR nicht leer bleiben soll. Wieviel 
Zeit bleibt, hängt also stark davon ab, was in der ISR gemacht werden 
soll.  Die andere Frage wäre, warum du denn überhaupt eine so hoch 
getaktete ISR brauchst.

von ATMEGA644V (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Das läuft bei mir aber so nicht durch den Compiler. Da fehlen die Header
> und die Funktion pulsePIN().

Ja Header habe ich weggelassen.

Aber ich habe mir das mit den 1µs wirklich nicht gerade gut überlegt.
Werde das um den Faktor 64 reduzieren (resp. multiplizieren) und dann 
kucke ich nochmal.

Gruss

von ATMEGA644V (Gast)


Lesenswert?

So, habe jetzt einen Interrupt ca. alle 820µs (reicht immer noch locker, 
weiss nicht genau was ich mir da überlegt habe).

Funktioniert 1A, danke für eure Hilfestellung (manchmal sieht man echt 
den Wald vor läuter Bäumen nicht mehr :P)

von Falk B. (falk)


Lesenswert?

@ATMEGA644V (Gast)

>Aber ich habe mir das mit den 1µs wirklich nicht gerade gut überlegt.
>Werde das um den Faktor 64 reduzieren (resp. multiplizieren) und dann
>kucke ich nochmal.

Wie wäre es, wenn du uns sagst was INSGESAMT rauskommen soll? Dann kann 
man dir auch helfen, siehe Netiquette.

von ATMEGA644V (Gast)


Lesenswert?

Naja, das wäre eine ziemlich lange Erklärung und eine komplizierte und 
sie ist eigentlich auch absolut nicht notwendig, denn alle haben 
verstanden was ich mache :)

von Falk B. (falk)


Lesenswert?

@ ATMEGA644V (Gast)

>sie ist eigentlich auch absolut nicht notwendig, denn alle haben
>verstanden was ich mache :)

Haben sie das? Nur ich nicht? Naja, was soll's

von ATMEGA644V (Gast)


Lesenswert?

Falk Brunner schrieb:
> Haben sie das? Nur ich nicht? Naja, was soll's

Und trotzdem hast du mir nützliche Informationen geliefert.
Also so weit daneben bist du wohl auch nicht gelegen :)

von Felix P. (fixxl)


Lesenswert?

Abgesehen vom ursprünglichen Problem: Wie kommst du eigentlich darauf, 
dass bei deiner Initialisierung von Timer 0 und einer Taktfrequenz von 
20 MHz jede µs ein Interrupt ausgelöst wird?

Für mich ergeben sich für die Zeit bis zum Timer 0 Overflow
t = 256 / 20000000 s = 12,8 µs.

von Peter D. (peda)


Lesenswert?

ATMEGA644V schrieb im Beitrag #3115425:
> Also so weit daneben bist du wohl auch nicht gelegen :)

Er hat nur gesehen, was Du da machst, aber nicht, warum Du es so machen 
willst (wie alle anderen auch).

Neulich war auch jemand, der 8 saukurze (<1µs) Impulse an 8 Eingängen 
genau nacheinander erkennen wollte oder daß sie 500000µs lang nicht 
kommen.
Und alle rätselten, wozu sowas bloß dienen könnte.

In den aller seltensten Fällen, wo jemand sagt: "so musses", stimmt das 
auch.
Mit Erklärung der Aufgabe wären die Lösungen viel einfacher.

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.