Armins AVR-Buch - Interrupts

Zuletzt geändert am 09.12.2023, 17:23:40

Interrupts


(armin77, 27.01.2013, 09:28:30)

Wenn man Statusänderungen eines Port`s erkennen möchte ohne ihn ständig abfragen zu müssen
braucht man einen Interrupt.
Er eignet sich hervorragend um Drehzahen oder Frequenzen zu messen.
Der Schalter/Taster der an den Interrupt--Eingang angeschlossen wird muß entprellt sein.
Der ATMega 8 hat gleich 2 Interrupt-Eingänge.
Das sind Pind.2(INT0) und Pind.3(INT1)
Der Vorteil ist, daß das Programm immer läuft und nur unterbrochen wird wenn der Schalter/Taster betätigt wird.
Bevor man die Interrupts benutzen kann müssen sie konfiguriert werden.

$regfile = "m8def.dat"
$Crystal=1000000
$hwstack=40
$swstack=16
$framesize = 32

Config Pind.2 = Input
Portd.2 = 1 'Pullup-Widerstand aktivieren

On Int0 Unterprogramm 'wenn INT0 dann ins Unterprogramm springen
Config Int0 = ..


Config Int0 =Falling
Der Interrupt wird bei Signalwechsel von 1 nach 0 ausgelöst

Config Int0 =Rising
Der Interrupt wird bei Signalwechsel von 0 nach 1 ausgelöst

Config Int0 =Change

Der Interrupt wird bei Signalwechsel ausgelöst


Zusätzlich kommt eine "Interrupt Service Routine" (ISR) dazu.
In der steht drin was das Programm tun soll wenn der Interrupt auftritt.
Da das Programm bei einem Interrupt angehalten wird sollte die ISR so kurz wie möglich sein.
Am besten setzt man dort nur eine Variable und wertet diese im Hauptprogramm aus

Das komplette Grundgerüst sieht dann so aus:

$regfile = "m8def.dat"
$Crystal=1000000
$hwstack=40
$swstack=16
$framesize = 32

Config Pind.2 = Input
Portd.2 = 1 'Pullup-Widerstand aktivieren

On Int0 Unterprogramm 'wenn interrupt dann ISR "Unterprogramm" aufrufen
Config Int0 = Rising 'Bei steigender Flanke Interrupt auslösen
Enable Int0 'Interrupt INT0 einschalten
Enable Interrupts ' alle Interrupts einschalten


Do
'Hier steht das Hauptprogramm

Loop
End

Unterprogramm:

'Befehle ausführen wenn Interrupt aufgetreten ist

Return



Hier ein Beispielprogramm.
An Pind.2 ist ein entprellter Taster angeschlossen.
An Portb.0 und Portb.1 eine LED mit Vorwiderstand.

$regfile = "m8def.dat"
$Crystal=1000000
$hwstack=40
$swstack=16
$framesize = 32

Config Pind.2 = Input
Portd.2 = 1 'Pullup-Widerstand aktivieren
Config Portb.1 = Output
Config Portb.0 = Output
On Int0 Unterprogramm 'wenn interrupt dann ISR Unterprogramm aufrufen
Config Int0 = Rising 'Bei steigender Flanke Interrupt auslösen
Enable Int0 'Interrupt INT0 einschalten
Enable Interrupts ' alle Interrupts einschalten


Do
Toggle Portb.0
Wait 1
Loop
End

Unterprogramm:

Toggle Portb.1

Return