mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt deaktivieren???


Autor: Andy Nagel (Gast)
Datum:

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

Autor: Andy Nagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe mich oben vertippt:
in der while-Schleife NICHT == sondern !=

Autor: johnny.m (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: inoffizieller WM-Rahul (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: Andy Nagel (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

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

Autor: Andy Nagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Jetzt funktioniert alles so wie ich haben möchte!

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

Autor: johnny.m (Gast)
Datum:

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

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.