Hallo, hab das unten aufgeführte Programm gschrieben. Leider kann ich die Pin-changed Interruptrotine nicht disablen. Müsste doch mit cli(); funktionieren. Leider durchläuft er bei einem Interrupt die Rotine desöfteren. Die Tasten sind nicht entprellt, möchte ich hinzufügen, was jedoch egal sein müsste, da man ja beim ersten Durchlauf der ISR der Interrupt disabled wird. Bin über jeden Tip dankbar. Im Voraus Danke! Grüsse Tom #include <avr\io.h> #include <avr\signal.h> #include <avr\interrupt.h> #include <stdlib.h> #include "init.h" #include "display_4bit.h" char nummer = 0; BYTE nummer_buffer[2]={'0','0'}; INTERRUPT(SIG_PIN_CHANGE1) { cli( ); nummer++; } void Byte2Ascii(BYTE array[2],BYTE zahl) { array[0]= (zahl%10)|0x30; // |0x30 für Ascii-Umwandlung array[1]= (zahl/10)|0x30; // |0x30 für Ascii-Umwandlung } void main (void) { DDRC=0x00; lcd_init(); lcd_command_out(lcd_on);// Display ein sbi(PCICR, PCIE1); // PIN-CHASNGE-Interrupt aktivieren PCMSK1=0xFF; // alle Eingängedes PortC für ISR aktivieren sei(); // Interrupts zulassen for (;;) // Endlosschleife { lcd_string_out("Interuptnr. ",1); lcd_position_set(1,14); Byte2Ascii(nummer_buffer,nummer); lcd_data_out(nummer_buffer[1]); //Anzahl Durchläufe derISR lcd_data_out(nummer_buffer[0]); //Anzahl Durchläufe derISR } }
Du kennst den Unterschied zwischen INTERRUPT und SIGNAL? Falls nicht: benutze SIGNAL...
Auch mit SIGNAL kein disablen möglich. Gibs zwischen SIGNAL und INTERRUPT einen Unterschied?
Hi bei einem reti wird das globale Interrup Flag immer gesetzt. cli(); hat in einer ISR deshalb keine Wirkung. Matthias
Du solltest auch nicht das Globale-Interruptflag löschen, sondern den Pin-Change-Interrupt ausschalten: [..] PCICR &= ~(1 << PCIE1); [..] Und: Ja! Es gibt einen gewaltigen Unterschied zwischen INTERRUPT und SIGNAL, steht aber genauestens in der Doku der avr-libc beschrieben... Da steht übrigens auch, daß sbi/cbi und Co abgekündigt sind, also nicht mehr verwenden. Lieber gleich an die "richtige" Schreibweise gewöhnen :)
cli() funktioniert und tut genau das, was es soll: alle Interrupts disablen. Und es tut auch nicht einen Fatz mehr, d.h. es setzt keine Interruptflags zurück. Wäre ja auch schlimm, dann könnte man nämlich keine Interrupts pollen oder würde Interrupts verlieren. Anders gesagt, wenn ein Interruptflag ausgelöst wurde und Du führst nach 10 Jahren ein sei() aus, dann wird der Interrupt auch schön abgearbeitet, genau wie es sein soll. Will man das nicht, dann muß man vor der Freigabe das Interruptflag löschen (auf 1 setzen). Der Pin-Change Interupt ist bei den meisten AVRs ziemlich witzlos. Man kann nicht die Pins auswählen und auch nicht erkennen, welcher Pin ihn ausgelöst hat. Er eignet sich daher nur zum Aufwachen des AVRs. Und nach dem Aufwachen sollte man ihn sofort disablen, will man nicht mit Interrupts zugebombt werden. Peter
> cli() funktioniert und tut genau das, was es soll: alle Interrupts > disablen. Klar, aber innerhalb einer ISR ist das eine teure Form eines NOPs: die Interrupts sind bereits abgeschaltet, und sie werden beim RETI wieder zugeschaltet, unabhängig davon, wie viele Male der Programmierer zwischendrin das bereits gelöschte Interruptflag nochmal gelöscht hat.
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.