Difference between revisions of "AVR Embedded Tutorial - GPIO-Interrupt/de"

From Free Pascal wiki
Jump to navigationJump to search
m (→‎Interrupt Routine: Fixed code comment)
 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Translate}}
+
{{LanguageBar}}
 
 
{{Warning| In Arbeit}}
 
  
 
=GPIO Interrupt=
 
=GPIO Interrupt=
  
 
==Vorwort==
 
==Vorwort==
 +
 
Wie man die GPIO und UART ansteuert, steht hier:
 
Wie man die GPIO und UART ansteuert, steht hier:
 +
 
* [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO]]
 
* [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO]]
 
* [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...''
 
* [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...''
  
==INT0 + INT1==
+
==Externe Interrupt==
kommt noch
+
 
 +
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.
 +
 
 +
<syntaxhighlight lang="pascal">
 +
procedure Int0_Interrupt; public Name 'INT0_ISR'; interrupt;
 +
begin
 +
  UARTSendString('INT0'); // Identify interrupt
 +
end;
 +
</syntaxhighlight>
 +
 
 +
===Interrupt aktivieren===
 +
 
 +
Die Parameter sind in der Tabelle weiter unten beschrieben.
 +
 
 +
<syntaxhighlight lang="pascal">
 +
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.
 +
</syntaxhighlight>
 +
 
 +
===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.
 +
 
 +
{| class="wikitable"
 +
|-
 +
! !! colspan="2"| INT1 !!!! colspan="2"| 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.
 +
 
 +
<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==
 +
 
Dieses Beispiel ist für einen Arduino Nano (Atmega328p).
 
Dieses Beispiel ist für einen Arduino Nano (Atmega328p).
  
 
===Terminal Ausgabe===
 
===Terminal Ausgabe===
 +
 
Gibt den Pin-Status auf einem Terminal aus.
 
Gibt den Pin-Status auf einem Terminal aus.
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
   procedure WritePort(p: byte);
 
   procedure WritePort(p: byte);
Line 30: Line 115:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Interrupt===
+
===Interrupt Routine===
 +
 
 
Wird bei einer Änderung eines Pines ausgelöst.
 
Wird bei einer Änderung eines Pines ausgelöst.
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
   procedure PC_Int0_Interrupt; public Name 'PCINT0_ISR'; interrupt;
 
   procedure PC_Int0_Interrupt; public Name 'PCINT0_ISR'; interrupt;
Line 45: Line 132:
  
 
===Pin Change GPIO deklarieren===
 
===Pin Change GPIO deklarieren===
 +
 
PB0, PB1, PB2 und BP3 für Interrupt aktivieren.
 
PB0, PB1, PB2 und BP3 für Interrupt aktivieren.
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
const
 
const
Line 52: Line 141:
  
 
===Pin Change Interrupt aktivieren===
 
===Pin Change Interrupt aktivieren===
 +
 +
Die Parameter sind in der Tabelle weiter unten beschrieben.
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
begin
 
begin
   DDRB := 0;
+
   DDRB := 0;
 
   PORTB := inPortsB; // PullUp
 
   PORTB := inPortsB; // PullUp
  
Line 60: Line 152:
 
   UARTInit;
 
   UARTInit;
  
   // PC_INT0 aktivieren
+
   // PCINT0_ISR aktivieren
   PCICR := %001; // Nur auf PORTB
+
   PCICR := %001; // Nur auf PORTB
 
   PCMSK0 := inPortsB;
 
   PCMSK0 := inPortsB;
  
Line 75: Line 167:
  
 
===Register für den Atmega328p===
 
===Register für den Atmega328p===
 +
 
Folgende Register sind für die Aktivierung der Ports / Pins zuständig:
 
Folgende Register sind für die Aktivierung der Ports / Pins zuständig:
 +
 
* '''PCICR''': Ports, welche einem Interrupt auslösen.  
 
* '''PCICR''': Ports, welche einem Interrupt auslösen.  
 
* '''PCMSKx''': Die einzelnen Pins.  
 
* '''PCMSKx''': Die einzelnen Pins.  
  
 
Tabelle für '''PCICR''':
 
Tabelle für '''PCICR''':
 +
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 87: Line 182:
 
|}
 
|}
  
Tabelle für '''PCMSKx''':
+
Tabelle für die Pins von '''PCMSKx''':
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 99: Line 195:
 
|}
 
|}
  
[[Category:AVR]] {{AutoCategory}}
+
===Beispiel für PORTB und PORTC===
 +
 
 +
<syntaxhighlight lang="pascal">
 +
  // 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;
 +
</syntaxhighlight>
 +
 
 +
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.
 +
 
 +
<syntaxhighlight lang="pascal">
 +
  procedure PC_Int1_Interrupt; public Name 'PCINT1_ISR'; interrupt;
 +
  begin
 +
    // mache Irgendwas
 +
  end;
 +
</syntaxhighlight>
 +
 
 +
= Siehe auch =
 +
 
 +
* Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
 +
 
 +
Autor: [[User:Mathias|Mathias]]
 +
 
 +
[[Category:Embedded/de]]
 +
[[Category:AVR/de]]
 +
[[Category:Arduino/de]]
 +
[[Category:Tutorials/de]]
 +
{{AutoCategory}}

Latest revision as of 13:47, 23 January 2020

Deutsch (de) English (en)

GPIO Interrupt

Vorwort

Wie man die GPIO und UART ansteuert, steht hier:

  • GPIO
  • UART UARTInit und UARTSendString(...

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

Autor: Mathias