GPIO Programmierung

Aus C und Assembler mit Raspberry

In diesem Kapitel werden wir uns mit der GPIO-Programmierung (General Purpose Input/Output) auf dem Raspberry Pi beschäftigen. Dazu besprechen wir:

  • Grundlagen der GPIO-Programmierung
  • Direkte Steuerung der GPIO-Pins
  • Besondere Register und Konfiguration
  • Grundlagen der GPIO-Programmierung

Grundlagen der GPIO-Programmierung

GPIO steht für "General Purpose Input/Output" und bezieht sich auf die universell einsetzbaren Pins auf dem Raspberry Pi, die zur Kommunikation mit der Außenwelt verwendet werden können. Diese Pins können als Eingang oder Ausgang konfiguriert werden und sind nützlich für eine Vielzahl von Projekten, wie das Ansteuern von LEDs, das Lesen von Sensorwerten oder die Kommunikation mit anderen Geräten.

Einige häufige Anwendungen von GPIOs umfassen:

  • Steuern von Leuchtdioden (LEDs)
  • Lesen von Tasterzuständen
  • Ansteuern von Relais
  • Kommunikation mit anderen Mikrocontrollern oder Sensoren

Direkte Steuerung der GPIO-Pins

Die direkte Steuerung der GPIO-Pins erfolgt durch Schreiben in bestimmte Register, die die Funktion und den Zustand der GPIOs festlegen. Auf dem Raspberry Pi gibt es spezielle Speicheradressen, die diesen Registern entsprechen. Diese Register beinhalten beispielsweise die GPIO Function Select Register (GPFSEL), die GPIO Set Register (GPSET) und die GPIO Clear Register (GPCLR).

Die Base-Adresse des GPIO-Registers für den Raspberry Pi 4 ist 0xFE000000, wobei die GPIO-Register bei einem Offset von 0x200000 beginnen, also 0xFE200000.

Für andere Raspberry Pi Varianten gibt es unter Basisadressen der Modelle eine Übersicht der Base-Adresse.

Besondere Register und Konfiguration

Die wichtigen Register zur Steuerung der GPIOs umfassen:

GPFSEL (GPIO Function Select Register)

Diese Register konfigurieren, ob ein GPIO-Pin als Eingang, Ausgang oder einer alternativen Funktion arbeitet. Für jeden GPIO-Pin sind 3 Bits vorhanden (000 für Eingang, 001 für Ausgang, andere Werte für Alternativfunktionen).

Beispiel:

  • GPFSEL0: Steuerung der Pins 0-9
  • GPFSEL1: Steuerung der Pins 10-19
  • GPFSEL4: Steuerung der Pins 40-49 (z.B., GPIO 42)

GPSET (GPIO Set Register)

Diese Register setzen bestimmte GPIO-Pins auf High.

GPSET0 setzt die Pins 0-31, GPSET1 setzt die Pins 32-57.

GPCLR (GPIO Clear Register)

Diese Register setzen bestimmte GPIO-Pins auf Low.

GPCLR0 setzt die Pins 0-31, GPCLR1 setzt die Pins 32-57.

Hinweis: Wenn die Base-Adresse der GPIO-Register lautet 0xFE200000:

  • GPFSEL0 bei 0xFE200004, GPSET1 bei 0xFE200020, GPCLR1 bei 0xFE20002C.

Beispiel: Interne LED steuern

Um die interne LED des Raspberry Pi über einen GPIO-Pin zu steuern (typischerweise GPIO 42 bei Raspberry Pi 4), können wir die folgenden Schritte ausführen:

Konfigurieren des GPIO-Pins 42 als Ausgang Umschalten des GPIO-Pins 42 auf High (LED an) Umschalten des GPIO-Pins 42 auf Low (LED aus)

Beispiel in Assembler:

.section .text
.global _start

_start:
    // Set GPIO42 as output
    ldr x0, =0xFE200010    // GPFSEL4 (GPIO Function Select Register 4)
    ldr x1, [x0]           // Lade den aktuellen Wert von GPFSEL4
    bic x1, x1, #(0x7 << 6) // Lösche die Bits 6-8 (funktion für GPIO42 wählen)
    orr x1, x1, #(0x1 << 6) // Setze GPIO42 als Ausgang (001 << 6)
    str x1, [x0]           // Schreibe den neuen Wert zurück in GPFSEL4

    // Turn GPIO42 on (LED an)
    ldr x0, =0xFE200020    // GPSET1 (GPIO Set Register 1)
    mov x1, #(1 << 10)     // Setze Bit 10 (GPIO42)
    str x1, [x0]

    // Warte (einfache Schleife für Verzögerung)
    mov x2, #1000000
wait:
    subs x2, x2, #1
    bne wait

    // Turn GPIO42 off (LED aus)
    ldr x0, =0xFE20002C    // GPCLR1 (GPIO Clear Register 1)
    mov x1, #(1 << 10)     // Lösche Bit 10 (GPIO42)
    str x1, [x0]

    // Warte (einfache Schleife für Verzögerung)
    mov x2, #1000000
wait2:
    subs x2, x2, #1
    bne wait2
    
    // Loop indefinitely
    b _start

Erklärung:

  • Der GPIO-Pin 42 wird als Ausgang konfiguriert, indem das GPIO Function Select Register (GPFSEL4) entsprechend gesetzt wird.
  • Der GPIO-Pin 42 wird auf High gesetzt (LED an), indem das GPIO Set Register (GPSET1) verwendet wird.
  • Eine einfache Wartezeit für eine Verzögerung wurde implementiert.
  • Der GPIO-Pin 42 wird wieder auf Low gesetzt (LED aus), indem das GPIO Clear Register (GPCLR1) verwendet wird.
  • Eine weitere Wartezeit für eine Verzögerung wurde hinzugefügt.
  • Das Programm springt schließlich zurück zum Anfang und wiederholt den Prozess.

Verweis auf Dokumentation

Für eine umfassende Liste von GPIO-Registers und deren Funktionen, konsultieren Sie die offizielle Dokumentation des Raspberry Pi oder andere technische Referenzen.