mikrocontroller.net

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


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher uC?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AtMega 16

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Interrupt.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die ausführliche Antwort.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.