AVR Embedded Tutorial - GPIO-Interrupt/de
│ Deutsch (de) │ English (en) │
GPIO Interrupt
Vorwort
Wie man die GPIO und UART ansteuert, steht hier:
Externe Interrupt
Interrupt Pin-Belegung beim ATmega328:
- INT0: PD2
- INT1: PD3
Interrupt Routine
Diese Beispiel zeigt wie dies beim INT0 geht. Wann der Interrupt ausgelöst wird, gibt man mit EICRA an. Siehe Tabelle weiter unten. Man kann auch INT0 und INT1 gleichzeitig aktivieren.
procedure Int0_Interrupt; public Name 'INT0_ISR'; interrupt;
begin
UARTSendString('INT0'); // Identify interrupt
end;
Interrupt aktivieren
Die Parameter sind in der Tabelle weiter unten beschrieben.
begin
PORTD := %00001100; // PullUp Pin 2 + 3
// UART inizialisieren
UARTInit;
// INT0 aktivieren
EICRA := %11; // INT0 wird ausgelöst, wen der Pin auf HIGH geht.
EIMSK := %01; // INT0 aktivieren.
// Interrupt aktivieren
asm Sei end;
// Hauptschleife
repeat
until 1 = 2;
end.
Register für den Atmega328p
Folgende Register sind für die Aktivierung der Ports / Pins zuständig:
- EICRA: Funktion des Interrupt.
- EIMSK: INT0 und/oder INT1 aktivieren.
Tabelle für EICRA, sie zeigt, bei was für einer Aktion am Pin ein Interrupt ausgelöst wird.
INT1 | INT0 | |||||
---|---|---|---|---|---|---|
Bit | 3 | 2 | 1 | 0 | ||
0 | 0 | 0 | 0 | Low Level am Pin | ||
0 | 1 | 0 | 1 | Jede Änderung | ||
1 | 0 | 1 | 0 | Pin auf LOW | ||
1 | 1 | 1 | 1 | Pin auf HIGH |
INT1
Der INT1 muss folgendermassen eingestellt werden.
EICRA := %1100; // INT1 wird ausgelöst, wen der Pin auf HIGH geht.
EIMSK := %10; // INT1 aktivieren.
Für den INT1 muss man die ISR-Procedure für den INT1 nehmen (INT1_ISR).
procedure Int1_Interrupt; public Name 'INT1_ISR'; interrupt;
begin
// mache Irgendwas
end;
Pin Change Interrupt
Dieses Beispiel ist für einen Arduino Nano (Atmega328p).
Terminal Ausgabe
Gibt den Pin-Status auf einem Terminal aus.
procedure WritePort(p: byte);
begin
UARTSendString('PB' + char(p + 48) + ' : ');
if PinB and (1 shl p) = (1 shl p) then begin
UARTSendString('HIGH ');
end else begin
UARTSendString('LOW ');
end;
end;
Interrupt Routine
Wird bei einer Änderung eines Pines ausgelöst.
procedure PC_Int0_Interrupt; public Name 'PCINT0_ISR'; interrupt;
var
i: byte;
begin
UARTSendString(#27'[0;0H'); // Cursor home
for i := 0 to 3 do begin
WritePort(i);
end;
end;
Pin Change GPIO deklarieren
PB0, PB1, PB2 und BP3 für Interrupt aktivieren.
const
inPortsB = %00001111; // PCINT0 + PCINT1 + PCINT2 + PCINT3
Pin Change Interrupt aktivieren
Die Parameter sind in der Tabelle weiter unten beschrieben.
begin
DDRB := 0;
PORTB := inPortsB; // PullUp
// UART inizialisieren
UARTInit;
// PCINT0_ISR aktivieren
PCICR := %001; // Nur auf PORTB
PCMSK0 := inPortsB;
// Interrupt aktivieren
asm Sei end;
// Hauptschleife
repeat
// mache Irgendwas
until 1 = 2;
end.
Register für den Atmega328p
Folgende Register sind für die Aktivierung der Ports / Pins zuständig:
- PCICR: Ports, welche einem Interrupt auslösen.
- PCMSKx: Die einzelnen Pins.
Tabelle für PCICR:
Bit | 2 | 1 | 0 |
---|---|---|---|
PCICR | PORTD | PORTC | PORTB |
Tabelle für die Pins von PCMSKx:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
PCMSK0 | PCINT7 | PCINT6 | PCINT5 | PCINT4 | PCINT3 | PCINT2 | PCINT1 | PCINT0 |
PCMSK1 | PCINT14 | PCINT13 | PCINT12 | PCINT11 | PCINT10 | PCINT9 | PCINT8 | |
PCMSK2 | PCINT23 | PCINT22 | PCINT21 | PCINT20 | PCINT19 | PCINT18 | PCINT17 | PCINT6 |
Beispiel für PORTB und PORTC
// PCINT0_ISR und PCINT1_ISR aktivieren
PCICR := %011; // PORTB und PORTC
PCMSK0 := %11000000 // Pin 6 + 7 von PORTB;
PCMSK1 := %00000011 // Pin 0 + 1 von PORTC;
Für den PCINT1_ISR kommt noch eine 2. ISR-Procedure dazu. Wen man PORTD auch noch verwenden würde, dann würde noch eine Procedure mit PCINT2_ISR dazukommen.
procedure PC_Int1_Interrupt; public Name 'PCINT1_ISR'; interrupt;
begin
// mache Irgendwas
end;
Siehe auch
- Übersichtseite AVR Embedded Tutorial
Autor: Mathias