Hallo!
Ich möchte die Interrupts näher kennenlernen. Ich habe einen Atmega8 und programmiere mit C.
Habe eine Programm geschrieben mit dem man eine LED mit nur einen Taster immer wieder ein und aus schalten kann. Leider ist der Atmega dann nur mit dieser einen Aufgabe beschäftigt, weil das Programm ständig den Pin abfragt, an dem der Taster angeschlossen ist. Deswegen möchte ich es jetzt mal mit Interrupts versuchen.
Ich denke mal, dass ich für meine Anwendung einen externen Interrupt brauchte, der anspringt, wenn der Taster gedrückt wird. Aber wie sieht sowas als Programm aus? Ich hab mich schon ein wenig schlau auf mikrocontroller.net gemacht.
Da gibt es z.B. ein Register General Interrupt Mask Register (GIMSK), welches ich wahrscheinlich brauche. Wenn ich in diesem Register das Bit 7 und/oder das Bit6 setze, dann aktiviert das den Pin PD2 (Int0) und den Pin PD3 (Int1) meines Atmegas, an den ich dann einen Taster(der ja den Interrupt auslösen soll) anschließen kann.
Als nächstes gibt´s dann das General Interrupt Flag Register (GIFR). Hier muss ich wohl kein Bit setzen. Das macht der Atmega allein (Bit 7 und/oder das Bit 6), wenn eine Aktion an Int0 oder Int1 stattfindet bzw. nimmt es wieder weg, wenn die Interruptroutine abgelaufen ist. Auf microcontroller.net heißt das irgendwie flag??? Und man muss aufpassen, weil eine 1 bedeutet, dass das Flag gelöscht ist und eine 0 bedeutet, dass das Flag aktiv ist.
Dann gibt´s da noch das MCU Control Register. Für meine Anwendung dürften da primär, das Bit 3/Bit 2 und das Bit 1/Bit 0 (ISC11/ISC10 und ISC01/00) nützlich sein. Sollte ich den Taster an Int1 anschließen, dann müssten ich die Bits3 und 2 betrachten. Bit 3 bekommt eine 1 und Bit 2 bekommt auch eine 1 (für steigende Flanke: Taster wird gedrückt).
Wozu brauche ich die Makros sei() und cli() ?? Sind die wichtig?
Jetzt heißt es da auf mikrocontroller.net: „Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) ISR.“
So weit so gut!
Aber wie sage ich dem Atmega jetzt konkret, dass er, wenn der Taster gedrückt worden ist, er meine LED anmachen soll? Plötzlich gibt es Vektoren!?
Wenn ich jetzt so ein externen Interrupt habe, muss ich den dann vorher ganz oben im Programm mit: #define INT0_vect deklarieren? Und dann mit ISR(Vektorname) aufrufen?
Könnte mir wohl jemand ein Programm zeigen, wie das gemacht wird? Hat evtl. jemand von euch ein Link oder weiß, wo ich ein einfaches Beispielprogramm finde?
Dankeschön für die Mühe!
Gruß Sven
Ich möchte die Interrupts näher kennenlernen. Ich habe einen Atmega8 und programmiere mit C.
Habe eine Programm geschrieben mit dem man eine LED mit nur einen Taster immer wieder ein und aus schalten kann. Leider ist der Atmega dann nur mit dieser einen Aufgabe beschäftigt, weil das Programm ständig den Pin abfragt, an dem der Taster angeschlossen ist. Deswegen möchte ich es jetzt mal mit Interrupts versuchen.
Ich denke mal, dass ich für meine Anwendung einen externen Interrupt brauchte, der anspringt, wenn der Taster gedrückt wird. Aber wie sieht sowas als Programm aus? Ich hab mich schon ein wenig schlau auf mikrocontroller.net gemacht.
Da gibt es z.B. ein Register General Interrupt Mask Register (GIMSK), welches ich wahrscheinlich brauche. Wenn ich in diesem Register das Bit 7 und/oder das Bit6 setze, dann aktiviert das den Pin PD2 (Int0) und den Pin PD3 (Int1) meines Atmegas, an den ich dann einen Taster(der ja den Interrupt auslösen soll) anschließen kann.
Als nächstes gibt´s dann das General Interrupt Flag Register (GIFR). Hier muss ich wohl kein Bit setzen. Das macht der Atmega allein (Bit 7 und/oder das Bit 6), wenn eine Aktion an Int0 oder Int1 stattfindet bzw. nimmt es wieder weg, wenn die Interruptroutine abgelaufen ist. Auf microcontroller.net heißt das irgendwie flag??? Und man muss aufpassen, weil eine 1 bedeutet, dass das Flag gelöscht ist und eine 0 bedeutet, dass das Flag aktiv ist.
Dann gibt´s da noch das MCU Control Register. Für meine Anwendung dürften da primär, das Bit 3/Bit 2 und das Bit 1/Bit 0 (ISC11/ISC10 und ISC01/00) nützlich sein. Sollte ich den Taster an Int1 anschließen, dann müssten ich die Bits3 und 2 betrachten. Bit 3 bekommt eine 1 und Bit 2 bekommt auch eine 1 (für steigende Flanke: Taster wird gedrückt).
Wozu brauche ich die Makros sei() und cli() ?? Sind die wichtig?
Jetzt heißt es da auf mikrocontroller.net: „Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) ISR.“
So weit so gut!
Aber wie sage ich dem Atmega jetzt konkret, dass er, wenn der Taster gedrückt worden ist, er meine LED anmachen soll? Plötzlich gibt es Vektoren!?
Wenn ich jetzt so ein externen Interrupt habe, muss ich den dann vorher ganz oben im Programm mit: #define INT0_vect deklarieren? Und dann mit ISR(Vektorname) aufrufen?
Könnte mir wohl jemand ein Programm zeigen, wie das gemacht wird? Hat evtl. jemand von euch ein Link oder weiß, wo ich ein einfaches Beispielprogramm finde?
Dankeschön für die Mühe!
Gruß Sven