This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| de:examples:timer:periodic_interrupt [2010/09/08 17:30] – angelegt Wember | de:examples:timer:periodic_interrupt [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Periodische Interrupts ====== | ||
| + | // | ||
| + | |||
| + | ===== Theorie ===== | ||
| + | |||
| + | Ziel dieses praktischen Beispiels ist es, die Verwendung von Interrupts an Beispiel von Timern darzustellen. Interrupts sind Programmteile welche auf Ereignisse, die in einem Mikrocontroller stattfinden, | ||
| + | Es ist beispielsweise möglich eine LED durch Interrupts blinken zu lassen, so dass die Blinkfrequenz nicht von einem Programm abhängig ist. | ||
| + | |||
| + | ===== Übung ===== | ||
| + | |||
| + | Das folgende Programm zeigt wie Timer eingestellt werden, um einen Interrupt auszulösen. | ||
| + | Das Programm nutzt zwei LEDs des digitalen I/O Moduls. Der Status der roten LED wird mit einer Softwareverzögerung periodisch geändert, der Status der grünen LED wird geändert wenn ein Interrupt auftritt. Es gibt ein separates Beispiel für blinkende LEDs durch Softwareverzögerung, | ||
| + | |||
| + | Zu Beginn des Programms wird der 16-Bit Timer 1 mit der Funktion // | ||
| + | Der Teiler des Timers ist 1024 und der Wert des ICR1 beträgt 14400. Bei einer Taktfrequenz von 14,7456MHz umfasst eine Periode somit genau eine Sekunde. Dieses kann mit folgender Formel berechnet werden: | ||
| + | |||
| + | f = 14745600 Hz / 1024 / 14400 = 1 | ||
| + | |||
| + | Nachdem zugelassen wurde, dass ein Interrupt den maximalen Wert von Counter 1 erreicht, muss ein Interrupt auch global, also im Mikrocontroller, | ||
| + | Ein Interrupt wird im Programm durch die Makrofunktion ISR definiert, deren Parameter der Name des Interruptvektors ist. Im folgenden Beispiel beträgt der Interruptvektor des maximal erreichbaren Wertes von Counter 1 // | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // HomeLab Beispiel für blinkende LED aufgrund von Counter-Interrupts. | ||
| + | // Zum Vergleich blinkender LEDs aufgrund von Interrupts, | ||
| + | // gibt es parallel eine durch Softwareverzögerung blinkende LED. | ||
| + | // | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // | ||
| + | // Festlegung der Pins der LEDs. | ||
| + | // | ||
| + | pin led_red | ||
| + | pin led_green = PIN(C, 3); | ||
| + | |||
| + | // | ||
| + | // Interrupt | ||
| + | // | ||
| + | ISR(TIMER1_CAPT_vect) | ||
| + | { | ||
| + | // Status der grünen LED ändern. | ||
| + | pin_toggle(led_green); | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // Hauptprogramm. | ||
| + | // | ||
| + | int main(void) | ||
| + | { | ||
| + | // LED Pins als Output setzen. | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | // Timer in den CTC Modus setzen. | ||
| + | timer1_init_ctc( | ||
| + | TIMER1_PRESCALE_1024, | ||
| + | TIMER1_CTC_TOP_ICR); | ||
| + | |||
| + | // Maximaler Wert des Timers ist 14400, wodurch | ||
| + | // die Periode 1 s lang ist. | ||
| + | // Formel: 14,7456Mhz / 1024 = 14400 | ||
| + | timer1_set_input_capture_value(14400); | ||
| + | |||
| + | // Dem Interrupt erlauben, den Wert zu erreichen. | ||
| + | timer1_input_capture_interrupt_enable(true); | ||
| + | |||
| + | // Globalen Interrupt zulassen. | ||
| + | sei(); | ||
| + | |||
| + | // Endlosschleife. | ||
| + | while (true) | ||
| + | { | ||
| + | // Softwareverzögerung 1000 ms. | ||
| + | sw_delay_ms(1000); | ||
| + | |||
| + | // Status der roten LED ändern. | ||
| + | pin_toggle(led_red); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Zu Beginn des Programms sieht man, dass unabhängig davon was der Mikrocontroller gerade im Hauptprogramm macht, Interrupts stattfinden und die grüne LED blinkt. | ||
| + | |||
| + | Läuft das Programm ein paar Minuten wird ein entscheidender Aspekt deutlich, der im Rahmen der Softwareverzögerung nicht so einfach zu erkennen ist. Auch wenn die Verzögerung der blinkenden roten LED 1000 ms beträgt, ist die tatsächlich benötigte Zeit um einen Zyklus zu beenden länger. Das liegt daran, dass die Änderung vom LED-Status', | ||