Forum: Mikrocontroller und Digitale Elektronik Interrupts - Priorität und Ausführung


von Stefan (Gast)


Lesenswert?

Hallo zusammen,

Ich möchte mich mit einem Sinus synchronisieren und synchron bleiben.
Dazu benutze ich einen Input Capture Interrupt und stelle mir dann meine 
Interrupts für OCR1A bzw. OCR1B ein (synchronisierte Pulse 
(zeitversetzt)).

Dazu eine Frage: Was passiert wenn beide Interrupts zur selben Zeit 
eintreten sollten. Geht dann einer verloren oder werden diese 
nacheinander abgearbeitet?

Meine Idee ist den OCR1A / B Interrupt für eine Flag abfrage in das Main 
Programm reinzuziehen (Zeitfehler wäre akzeptabel) allerdings weiß ich 
nicht wie ich den Interrupt Flag abfragen und zurücksetzten kann. Der 
Code (siehe unten) funktioniert so nicht. Ich verstehe aber nicht warum.

Kann mir jemand die beiden Fragen beantworten?

Vielen Dank


---------------------
mein Programm in Auszügen

1. Register:

TCCR1B  =   (1 << ICES1) |(1 << CS11) | (1<<ICNC1);
TIMSK   =   (0<<TICIE1) | (0 << OCIE1A) | (0 << OCIE1B);


2. main

OCR1A = 3000;

if (TIFR && (1<<OCF1A) )
{

 // code

TIFR = (0<<OCF1A);
}

von Patrick (Gast)


Lesenswert?

Welcher uC?

von Stefan (Gast)


Lesenswert?

AtMega 16

von Falk B. (falk)


Lesenswert?

Siehe Interrupt.

von holger (Gast)


Lesenswert?

>if (TIFR && (1<<OCF1A) )

"&&" ist hier falsch.

Und dann noch das hier beachten:

OCF1A is automatically cleared when the Output Compare Match A Interrupt 
Vector is executed. Alternatively, OCF1A can be cleared by writing a 
logic one to its bit location.

von Stefan (Gast)


Lesenswert?

OCF1A is automatically cleared when the Output Compare Match A Interrupt
Vector is executed. Alternatively, OCF1A can be cleared by writing a
logic one to its bit location.

Heißt dies:
1 = Flag nicht gesetzt
0 = Flag gesetzt

also genau umgekehrt wie sonst?

von Oliver (Gast)


Lesenswert?

>Dazu eine Frage: Was passiert wenn beide Interrupts zur selben Zeit
>eintreten sollten. Geht dann einer verloren oder werden diese
>nacheinander abgearbeitet?

Das mit den Interrupts auf einem AVR funktioniert in etwa so (leicht 
vereinfacht):

Tritt ein Ereignis ein, welches einen Interrupt auslösen kann, so wird 
im enstprecheden Statusregister das zugehörige Interruptflag gesetzt. 
Dabei ist es egal, ob das Flag schon gesetzt war, oder nicht.

Der Prozessor prüft nach jedem Maschinenbefehl, ob ein Interruptflag 
gesetzt ist, und ob Interrupts global freigegeben sind. Ist das der 
Fall, springt er in die Interruptbehandlung, wenn nicht, arbeitet er den 
nächsten Befehl ab. Sollten zu dem Prüfungszeitpunkt mehrere 
Interruptflags gesetzt sein, so wird das mit der höchsten Priorität 
bearbeitet. Die Priorität ergibt sich aus der Position des Vektors in 
der Interrupttabelle, von oben nach unten. Beim Einsprung in die ISR 
wird das globale I-FLag automatisch gelöscht, so daß während der 
Abarbeitung der ISR diese nicht durch andere Interrupts unterbrochen 
werden kann.

Bei den allermeisten Interrupts wird zu Beginn der Interruptbearbeitung 
das zugehörige Flag automatisch gelöscht (Ausnahme ist z.B. das 
UART-RX-Interruptflag). Durch den Anwender lassen sich Interruptflags 
durch schreiben einer 1 auf das Flag löschen (klingt blöd, ist aber so).
Nach dem abschliesenden RETI einer ISR wird das globale I-Flag wieder 
gesetzt, und dann immer ein Befehl des normalen Programms abgearbeitet. 
Danach werden wieder die ISR-Flag geprüft, usw.

Damit lassen sich dann alle deine Fragen beantworten:

>Was passiert wenn beide Interrupts zur selben Zeit
>eintreten sollten. Geht dann einer verloren oder werden diese
>nacheinander abgearbeitet?

OCR1A bzw. TIMER1_COMPA hat die höhere Priorität, also wird der 
abgearbeitet, und dabei das zugehörige Flag OCF1A gelöscht. OCR1B hat 
OCF1B gesetzt, das bleibt einfach gesetzt, solange, bis der Prozessor 
mal Zeit findet, die zugehörige ISR abzuarbeiten, oder bis du es von 
Hand löschst.

>Meine Idee ist den OCR1A / B Interrupt für eine Flag abfrage in das Main
>Programm reinzuziehen (Zeitfehler wäre akzeptabel) allerdings weiß ich
>nicht wie ich den Interrupt Flag abfragen und zurücksetzten kann.

Siehe oben. Dafür darfst du allerdings den zugehörigen Interrupt nicht 
freigeben, sonst löscht der Prozessor das Flag, bevor du es überhaupt 
abfragen kannst.

Oliver

von Stefan (Gast)


Lesenswert?

Danke für die ausführliche Antwort.

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.