Forum: Mikrocontroller und Digitale Elektronik Interrupt deaktivieren???


von Andy Nagel (Gast)


Lesenswert?

Habe folgendes Problem:

Ich benutze einen ATmega128 und die exteren Interrupts
(INT4,INT5,INT6)
so wenn ich nacheinander die geforderten Flanken an
INT4--> INT5--> INT6--> bekomme..... ist alles OK!

Aber wenn ich zuerste an INT6 eine Flanke bekommen, owohl ich auf INT 4
warte löst der INT6 aus. WARUM ??? der ist doch deaktiviert.

mache ich irgendein fehler?




PROGRAMMAUSCHNITT-->

SIGNAL (SIG_INTERRUPT4)
{LS_1=0xff;}
SIGNAL (SIG_INTERRUPT5)
{LS_2=0xff;}
SIGNAL (SIG_INTERRUPT6)
{LS_3=0xff;}


int main(void)
{.....
EICRB|= (1<<ISC41)|(0<<ISC40); //INT4 löst bei einer negativer Flanke
aus
EICRB|= (1<<ISC51)|(0<<ISC50); //INT5 löst bei einer negativer Flanke
aus
EICRB|= (1<<ISC61)|(1<<ISC60); //INT6 löst bei einer positiven Flanke
aus

....

EIMSK|=(1<<INT4)|(0<<INT5)|(0<<INT6);  //INT4 aktivieren
while(LS_1==0xFF)
      {asm volatile "NOP");}
EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT4 deaktivieren
...........
EIMSK|=(0<<INT4)|(1<<INT5)|(0<<INT6);  //INT5 aktivieren
while(LS_2==0xFF)
      {asm volatile "NOP");}
EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT5 deaktivieren
...........
EIMSK|=(<<INT4)|(0<<INT5)|(1<<INT6);  //INT6 aktivieren
while(LS_3==0xFF)
      {asm volatile "NOP");}
EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT5 deaktivieren

von Andy Nagel (Gast)


Lesenswert?

habe mich oben vertippt:
in der while-Schleife NICHT == sondern !=

von johnny.m (Gast)


Lesenswert?

> EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT4 deaktivieren
> EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT5 deaktivieren
> EIMSK|=(0<<INT4)|(0<<INT5)|(0<<INT6);  //INT5 deaktivieren

Überlege mal, was Du da machst... Da wird gar nichts deaktiviert. Wenn
Du etwas mit einer Null veroderst, bleibt alles wie gehabt (X | 0 = X).
Ein Bit wird gelöscht, indem man es mit einer 0 verUNDet! Schau Dir das
mal im AVR-GCC-Tutorial an.

von johnny.m (Gast)


Lesenswert?

Im Klartext z.B.:
EIMSK &= ~(1<<INT4);  //INT4 deaktivieren

von inoffizieller WM-Rahul (Gast)


Lesenswert?

> 0<<INT6

Was passiert dabei? Genau: Nichts!

Guck dir mal C-Programme und das Verschieben von Bits an.
0<<INT6 verschiebt eine 0 um INT6-Stellen nach links.
Vorher 0, hinterher immer noch 0.

von Peter D. (peda)


Lesenswert?

Der Interruptlogik ist es vollkommen wurscht, wann das Triggerereignis
eintritt und wann Du den Interrupt behandelst.
Und wenn dazwischen 100 Jahre liegen sollten, wirds eben nach 100
Jahren behandelt

Wenn Du nicht willst, daß ein Interrupt uralte Ereignisse behandelt,
dann mußt Du eben das Ereignisflag unmittelbar vor der Freigabe
löschen.


Peter

von johnny.m (Gast)


Lesenswert?

Peter hat völlig recht. Wenn Du sowieso nur wartest, kannst Du die Flags
aber auch direkt im Hauptprogramm per Polling abfragen und Dir den
ganzen Interrupt-Kram sparen. Das Löschen eines Interrupt-Enable-Bits
sperrt nur die Bearbeitung des Interrupts und nicht den Interrupt
selber! Wenn ein Interrupt-Ereignis auftritt, wird in jedem Fall das
Flag gesetzt (falls es nicht schon gesetzt war), völlig unabhängig
davon, ob der Interrupt durch das INTx-Bit zur Bearbeitung freigegeben
ist oder nicht. Wenn er dann freigegeben wird und das Flag ist bereits
gesetzt und es stehen keine Interrupts höherer Priorität an, dann wird
der Interrupt sofort bearbeitet.

In Deinem Fall dürfte das allerdings an der Reihenfolge nichts ändern.
Der eigentliche Fehler ist (siehe oben...)

von Andy Nagel (Gast)


Lesenswert?

ich warte nicht nur..... habe die Abfrag vereinfacht, um das Problem
genauer zu zeigen.

also
EIFR=0x00; vor der Abfrage würde reichen?

Aber auch das funktioniert nicht. Stehe ich den so arg auf dem
Schlauch?

von johnny.m (Gast)


Lesenswert?

Interrupt-Flags werden gelöscht, indem man eine '1' hineinschreibt!
Lies Dir doch bitte bitte bitte mal den entsprechenden Abschnitt im
AVR-GCC-Tutorial durch, da steht alles Wissenswerte. Es gibt eigentlich
keinen Grund, das hier alles noch mal zu schreiben. Ich hoffe, Du hast
wenigstens die Änderungen von oben mittlerweile übernommen...

von Andy Nagel (Gast)


Lesenswert?

Danke!

Jetzt funktioniert alles so wie ich haben möchte!

Vielen Dank... und Sorry wegen den ANFÄNGERFRAGEN!

von johnny.m (Gast)


Lesenswert?

Eigentlich kein Problem, aber gerade für die ANFÄNGERFRAGEN ist doch das
Tutorial da...

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.