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
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
20MHZ.. ich habe im Netz versucht zu finden, wie lange so ein Aufruf dauert habe aber keine (zuverlässige) Aussage gefunden.
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.
EDIT: Das Problem besteht allerdings auch, wenn der Interrupt ca. jede Millisekunde ausgeführt wird.
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.
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?
@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!
ATMEGA644V schrieb im Beitrag #3115268: > Timer0-Overflow Interrupt (ca. jede us) Einen Interrupt pro Mikrosekunde? Bisschen krass.
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
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.
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).
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?
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).
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?
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..
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!).
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.
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
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)
@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.
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 :)
@ 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
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 :)
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.