Forum: Mikrocontroller und Digitale Elektronik Interrupts im Interrupt ausschalten


von Oz z. (ozzy)


Lesenswert?

Moin,

ich würde gerne, nachdem mein Timer0-Interrupt 250x ausgeführt wurde, 
diesen Interrupt kurz ausschalten, um die gesammelten Daten zu 
verarbeiten.

Doch leider klappt das so nicht:
1
ADC_counter++;
2
if (ADC_counter == 251 ) cli();
Geht so etwas denn gar nicht? Später möchte ich den Interrupt einfach 
wieder über sei() anschalten.


Vielen Dank für Eure Hilfe, Ozzy

von Johannes M. (johnny-m)


Lesenswert?

Christoph O. wrote:
> ich würde gerne, nachdem mein Timer0-Interrupt 250x ausgeführt wurde,
> diesen Interrupt kurz ausschalten, um die gesammelten Daten zu
> verarbeiten.
>
> Doch leider klappt das so nicht:
>
1
> ADC_counter++;
2
> if (ADC_counter == 251 ) cli();
3
>
Wenn das innerhalb der ISR steht, kann das nicht funktionieren, da die 
Hardware erstens beim Sprung in den Interrupt-Vektor sowieso automatisch 
das I-Bit löscht (also ein cli() macht, weshalb Dein cli() gar keinen 
Effekt hat) und zweitens dieses Bit beim Rücksprung ins Hauptprogramm 
genauso automatisch wieder setzt (also ein sei() macht).

> Geht so etwas denn gar nicht? Später möchte ich den Interrupt einfach
> wieder über sei() anschalten.
Warum versuchst Du dann, die Bearbeitung aller Interrupts zu sperren 
(was so aus o.g. Gründen nicht geht) und sperrst den Interrupt nicht 
lokal? Dafür hat schließlich jeder Interrupt sein lokales Freigabebit.

von Andreas K. (a-k)


Lesenswert?

Du musst das Enable-Bit der Interrupt-Quelle ausschalten (Timer, ADC, 
oder was auch immer das ist), nicht das Interrupt-Enable vom Prozessor. 
Das ist im Interrupt-Handler nämlich ohnehin ausgeschaltet, wird nämlich 
mit bei der Rückkehr wieder eingeschaltet.

von lkmiller (Gast)


Lesenswert?

>wird nämlich mit bei der Rückkehr wieder eingeschaltet
Und zwar implizit über das Restaurieren des SREGs (Bit7)

von Johannes M. (johnny-m)


Lesenswert?

lkmiller wrote:
>>wird nämlich mit bei der Rückkehr wieder eingeschaltet
> Und zwar implizit über das Restaurieren des SREGs (Bit7)
Das macht schon die Controller-Hardware selber (also selbst bei einer 
naked-ISR passiert das, obwohl dabei das SREG nicht extra gesichert 
wird). Selbst in Assembler (wo man das SREG "von Hand" sichern muss, 
wenn man es denn will) ist dem so...

von Oz z. (ozzy)


Lesenswert?

Hi,

vielen Dank für Eure Antworten - ein blöder Fehler von mir. Jetzt 
funktioniert es auch einwandfrei.

Vielen Dank noch einmal, Ozzy

von Peter D. (peda)


Lesenswert?

lkmiller wrote:
>>wird nämlich mit bei der Rückkehr wieder eingeschaltet
> Und zwar implizit über das Restaurieren des SREGs (Bit7)

Nö.
Das SREG im Interrupt hat immer das I-Bit gelöscht.
Erst das RETI setzt das I-Bit.


Peter

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Genau. Da kann der Anwender in der ISR restaurieren was er will, denn 
das RETI kommt immer nach der ISR. Interrupte, die nicht sein dürfen, 
sperrt man über die zuständigen Interrupt-Enable-Bits in den 
betreffenden I/O-Registern der peripheren Module und gibt sie erst 
wieder frei, wenn sie auch wirklich zuschlagen dürfen. Vorher sollte man 
ein eventuell schon aufgelaufenes Interrupt-Flag durch ein Schreiben 
einer logischen 1 löschen.

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.