Difference between revisions of "AVR Embedded Tutorial - GPIO-Interrupt/de"
Line 10: | Line 10: | ||
* [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...'' | * [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...'' | ||
− | ==INT0 | + | ==Externe Interrupt== |
+ | Interrupt Pin-Belegung beim ATmega328: | ||
+ | * INT0: PD2 | ||
+ | * INT1: PD3 | ||
===Interrupt Routine=== | ===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. | ||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
procedure Int0_Interrupt; public Name 'INT0_ISR'; interrupt; | procedure Int0_Interrupt; public Name 'INT0_ISR'; interrupt; | ||
Line 33: | Line 38: | ||
// INT0 aktivieren | // INT0 aktivieren | ||
− | EICRA := %11; // | + | EICRA := %11; // INT0 wird ausgelöst, wen der Pin auf HIGH geht. |
− | EIMSK := %01; | + | EIMSK := %01; // INT0 aktivieren. |
// Interrupt aktivieren | // Interrupt aktivieren | ||
Line 49: | Line 54: | ||
Tabelle für '''EICRA''', sie zeigt, bei was für einer Aktion am Pin ein Interrupt ausgelöst wird. | Tabelle für '''EICRA''', sie zeigt, bei was für einer Aktion am Pin ein Interrupt ausgelöst wird. | ||
− | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 64: | Line 68: | ||
| || 1 || 1 || || 1 || 1 || Pin auf HIGH | | || 1 || 1 || || 1 || 1 || Pin auf HIGH | ||
|} | |} | ||
+ | |||
+ | ===INT1=== | ||
+ | Der INT1 muss folgendermassen eingestellt werden. | ||
+ | <syntaxhighlight lang="pascal"> | ||
+ | EICRA := %1100; // INT1 wird ausgelöst, wen der Pin auf HIGH geht. | ||
+ | EIMSK := %10; // INT1 aktivieren. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Für den '''INT1''' muss man die ISR-Procedure für den '''INT1''' nehmen '''(INT1_ISR)'''. | ||
+ | |||
+ | <syntaxhighlight lang="pascal"> | ||
+ | procedure Int1_Interrupt; public Name 'INT1_ISR'; interrupt; | ||
+ | begin | ||
+ | // mache Irgendwas | ||
+ | end; | ||
+ | </syntaxhighlight> | ||
==Pin Change Interrupt== | ==Pin Change Interrupt== |
Revision as of 00:09, 13 November 2017
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;
var
i: integer;
begin
UARTSendString('INT0'); // Cursor home
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;
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;