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
> 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.
> 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.
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
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...)
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?
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...
Danke! Jetzt funktioniert alles so wie ich haben möchte! Vielen Dank... und Sorry wegen den ANFÄNGERFRAGEN!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.