SPI: Schnell, einfach, mit eigener Leitung für jedes Gerät

https://bildung.social/@oerinformatik/

https://oer-informatik.de/spi-bus

SPI, Serial Peripheral Interface, Mikrocontroller, Chip Select, SPI-Modus, Schieberegister, Daisy Chain, ESP32, ESP8266, Arduino, BME280, MAX7219

tl/dr; (ca. 28 min Lesezeit): SPI überträgt Daten zwischen Mikrocontroller und Peripheriegeräten mit Takten im Megahertz-Bereich und gleichzeitig in beide Richtungen. Du lernst die Kennzeichen der Schnittstelle kennen: vier Leitungen mit Gegentaktausgängen, eine eigene Auswahlleitung je Gerät, kein festes Protokoll und vier SPI-Modi. Du liest ein SPI-Impulsdiagramm, unterscheidest sternförmige Auswahlleitungen und Ketten und schließt Bausteine an Arduino, ESP8266 und ESP32 an – mit einer Checkliste, was Du vorher im Datenblatt und in der Bibliotheksdokumentation prüfen solltest, und einer Entscheidungshilfe zwischen SPI und I²C [AI-Assisted]. (Zuletzt geändert am 03.11.2026)

Disclaimer: Teile des Textes stammen von einer KI. Inhalte sind nicht automatisch zuverlässig; überprüfe Fakten und zitiere vertrauenswürdige Quellen.

Dieser Artikel ist Teil einer Artikelreihe zu Hardware-Schnittstellen von Mikrocontrollern: I²C / SPI

Schon fit in diesem Thema? Nutze die Kann-Liste und die Leitfragen unter dem Artikel als Checkliste, ob Du die relevanten Kompetenzen bereits hast.

Als SPI-Grundlagen kann ich nach Durchlesen des Artikels…

  • … die Kennzeichen von SPI nennen (synchron, seriell, vollduplex, keine Adressen, keine Bestätigung) und SPI von I²C unterscheiden.

  • … die Leitungen SCK, MOSI, MISO und CS mit ihren gebräuchlichen Alternativnamen zuordnen und ihre Aufgabe erklären.

  • … erklären, wie Controller und Peripheriegerät über einen Schieberegister-Ring gleichzeitig Daten austauschen.

  • … die vier SPI-Modi über CPOL und CPHA unterscheiden und den passenden Modus aus einem Datenblatt ablesen.

  • … ein SPI-Impulsdiagramm lesen und einen Registerzugriff (Lesen und Schreiben) beschreiben.

  • … mehrere Geräte mit eigenen CS-Leitungen oder als Kette (Daisy Chain) anschließen und die Zahl der benötigten Leitungen bestimmen.

  • … einen SPI-Baustein an Arduino Uno, ESP8266 oder ESP32 anschließen und mit der SPI-Bibliothek ansprechen.

  • … vor dem Anschluss eines Sensors oder Aktors anhand von Datenblatt und Bibliotheksdokumentation prüfen, ob Schnittstelle, Versorgung, Pegel, Takt, Umgebungsbedingungen und Speicherbedarf passen.

Darüber hinaus kann ich als SPI-Expertenwissen…

  • … Übertragungsdauern von SPI und I²C berechnen und begründet entscheiden, welche Schnittstelle für eine Anwendung passt.

  • … Pegelwandlung und Leitungsführung für schnelle SPI-Verbindungen planen.

  • … typische Fehlerbilder bei SPI eingrenzen, etwa nicht freigegebene MISO-Leitungen oder Startprobleme durch belegte Konfigurations-Pins.

Ein Farbdisplay mit 240 × 240 Pixeln braucht für ein einziges Bild bei 16 Bit Farbtiefe rund 115 KB. Eine SD-Karte soll Messwerte schneller speichern, als sie anfallen. Ein LED-Matrixtreiber soll eine Laufschrift flüssig bewegen. Für solche Datenmengen ist I²C zu langsam. Hier kommt SPI (Serial Peripheral Interface) ins Spiel: eine schlichte, aber schnelle Schnittstelle, bei der der Mikrocontroller jedes Gerät über eine eigene Leitung auswählt und Daten mit vielen Megahertz hin- und herschiebt.

SPI-Bus: ein ESP32 als Controller mit den gemeinsamen Leitungen SCK (GPIO18), MOSI (GPIO23) und MISO (GPIO19) zu einem BME280, einem TFT-Display ST7789 ohne MISO-Anschluss und einer microSD-Karte; jedes Gerät hat eine eigene, low-aktive CS-Leitung (GPIO5, GPIO17, GPIO16) (mit KI erstellt)

Steckbrief: Was SPI ausmacht

SPI wurde in den 1980er-Jahren von Motorola für die eigenen Mikrocontroller eingeführt. Anders als I²C gibt es keine verbindliche Spezifikation: SPI ist ein Quasi-Standard, den jeder Hersteller etwas anders auslegt. Was genau übertragen wird, in welchem Modus und mit welchem Takt, steht deshalb immer im Datenblatt des jeweiligen Bausteins. Die Rollen heißen klassisch Master und Slave, inzwischen meist Controller und Peripheral (Peripheriegerät).

Steckbrief SPI
Merkmal SPI
Übertragung seriell, Bit für Bit, meist höchstwertiges Bit zuerst
Takt synchron: Der Controller liefert den Takt auf einer eigenen Leitung (SCK)
Richtung vollduplex: getrennte Datenleitungen für beide Richtungen, gleichzeitig aktiv
Leitungen 3 gemeinsame Leitungen (SCK, MOSI, MISO) plus eine CS-Leitung je Gerät, dazu gemeinsame Masse
Auswahl der Geräte über die Auswahlleitung CS, keine Adressen
Ausgangsstufen Gegentakt (Push-Pull), keine Pull-ups nötig
Bestätigung keine; der Controller merkt nicht, ob ein Gerät zuhört
Protokoll keines festgelegt: Wortlänge, Befehle und Bedeutung der Bytes bestimmt der Baustein
Geschwindigkeit typisch 1 bis 20 MHz, je nach Baustein bis 80 MHz und mehr
Reichweite kurze Verbindungen auf der Platine oder im Gerät

Was SPI von I²C und anderen Schnittstellen unterscheidet:

  • Gleichzeitig senden und empfangen: Mit jedem Takt wandert ein Bit vom Controller zum Gerät und gleichzeitig eines zurück. SPI ist im Kern ein Ring aus zwei Schieberegistern.

  • Eine Leitung je Gerät statt Adressen: Der Controller wählt ein Gerät aus, indem er dessen CS-Leitung auf LOW zieht. Das kostet Pins, spart aber jeden Verwaltungsaufwand im Telegramm.

  • Schnell und schlank: Gegentaktausgänge erzeugen steile Flanken, und es gibt weder Adressbytes noch Bestätigungsbits. Deshalb erreicht SPI ein Vielfaches der Geschwindigkeit von I²C.

  • Kein Sicherheitsnetz: Ohne ACK merkt der Controller nicht, ob ein Gerät angeschlossen ist. Ein offener MISO-Eingang liefert dann je nach Pegel nur 0x00 oder 0xFF – ohne Fehlermeldung.

Leitungen und Potenziale

Weil es keinen verbindlichen Standard gibt, tragen die Leitungen in Datenblättern viele Namen. Die folgende Tabelle ordnet sie zu; die Richtungsangabe bezieht sich auf die Sicht des jeweiligen Bausteins.

Leitungen der SPI-Schnittstelle
Leitung Aufgabe Richtung weitere Bezeichnungen
SCK Takt (Serial Clock) Controller → Gerät SCLK, CLK, SCL (auf Modulen mit I²C und SPI)
MOSI Daten zum Gerät (Master Out, Slave In) Controller → Gerät COPI, am Controller SDO, am Gerät SDI, DIN, DI, SDA
MISO Daten zum Controller (Master In, Slave Out) Gerät → Controller CIPO, am Controller SDI, am Gerät SDO, DOUT, DO
CS Geräteauswahl (Chip Select), low-aktiv Controller → Gerät \overline{\mathrm{CS}}, SS (Slave Select), CSB, NSS, CE, LOAD
GND gemeinsames Bezugspotenzial – –

Die Bezeichnungen COPI und CIPO (Controller Out, Peripheral In bzw. umgekehrt) hat die Open Source Hardware Association 2020 vorgeschlagen; Arduino verwendet sie inzwischen in seiner Dokumentation. Beim Verdrahten gilt: MOSI an MOSI, MISO an MISO – anders als bei UART, wo TX und RX gekreuzt werden. Bei den Bezeichnungen SDI und SDO musst Du dagegen kreuzen, denn sie beschreiben die Sicht des jeweiligen Bausteins: SDO des Controllers an SDI des Geräts.

Schieberegister-Ring: Warum SPI vollduplex ist

In Controller und Gerät sitzt je ein Schieberegister, meist mit 8 Bit. Mit jedem Takt schiebt der Controller sein höchstwertiges Bit über MOSI hinaus, und das Gerät schiebt gleichzeitig sein höchstwertiges Bit über MISO zurück. Nach acht Takten haben beide Register ihren Inhalt getauscht.

Schieberegister-Ring: Das Register des Controllers enthält 0xD0, das des Peripheriegeräts 0x60; MOSI führt vom höchstwertigen Bit des Controllers zum niederwertigsten Ende des Geräts, MISO vom höchstwertigen Bit des Geräts zum Controller; nach 8 Takten enthält der Controller 0x60 und das Gerät 0xD0 (mit KI erstellt)

Das hat eine praktische Folge: Wer lesen will, muss senden. Will der Controller ein Byte vom Gerät haben, muss er acht Takte erzeugen und dafür irgendein Byte (ein sogenanntes Dummy-Byte, oft 0x00 oder 0xFF) hinausschieben. In der Arduino-Bibliothek heißt die zentrale Funktion deshalb SPI.transfer(): Sie sendet ein Byte und gibt das gleichzeitig empfangene zurück.

Gegentakt, CS und hochohmiges MISO

Alle SPI-Ausgänge sind Gegentaktausgänge: Sie treiben aktiv HIGH und aktiv LOW. Pull-up-Widerstände für den Datentransport sind deshalb nicht nötig, und die Flanken sind steil. Das funktioniert aber nur, wenn auf jeder Leitung genau ein Ausgang aktiv ist. Für SCK und MOSI ist das der Controller. Auf MISO hängen dagegen alle Geräte. Ein Gerät, dessen CS-Leitung HIGH ist, muss seinen MISO-Ausgang deshalb hochohmig schalten (Tri-State). Halten sich Geräte nicht daran – bei manchen günstigen microSD-Modulen mit eingebautem Pegelwandler ist das der Fall –, treiben zwei Ausgänge gegeneinander und der Bus funktioniert nicht mehr.

Zwei weitere Regeln für die Auswahlleitung:

  • CS ist low-aktiv: LOW heißt „ausgewählt“. Die fallende Flanke von CS markiert den Beginn einer Übertragung, die steigende das Ende. Viele Bausteine übernehmen erst bei der steigenden CS-Flanke die empfangenen Daten.

  • Solange der Mikrocontroller startet, sind seine Pins oft noch Eingänge und die CS-Leitungen undefiniert. Ein Pull-up-Widerstand an jeder CS-Leitung (z. B. 10 kΩ) hält alle Geräte in dieser Zeit sicher abgewählt. Bei SD-Karten ist das besonders wichtig.

Pegel und gemeinsame Masse

SPI legt keine Spannungspegel fest; es gelten die Pegel der beteiligten Bausteine. Alle Teilnehmer brauchen eine gemeinsame Masse, und die Logikpegel müssen zusammenpassen. Weil jede SPI-Leitung nur eine Richtung hat, reichen zur Pegelwandlung unidirektionale Treiber, die schnell genug für MHz-Takte sind:

  • 3,3 V → 5 V (SCK, MOSI, CS zu einem 5-V-Gerät): Ein Treiber mit TTL-kompatiblen Eingängen wie der 74AHCT125, der 3,3 V sicher als HIGH erkennt und mit 5 V weitergibt.

  • 5 V → 3,3 V (MISO von einem 5-V-Gerät, oder alle Leitungen zu einem 3,3-V-Gerät an einem 5-V-Controller): ein 74LVC125, dessen Eingänge 5 V vertragen, oder bei niedrigen Takten ein Spannungsteiler.

Die bidirektionalen MOSFET-Pegelwandler, die bei I²C gut funktionieren, sind für schnelle SPI-Takte oft zu langsam, weil auch bei ihnen Pull-ups die steigende Flanke formen. Ein typischer Fall ist der LED-Matrixtreiber MAX7219: Er wird mit 5 V versorgt und erwartet laut Datenblatt mindestens 3,5 V als HIGH. An einem ESP32 funktioniert er häufig trotzdem – zugesichert ist das aber nicht.

Mehrere Geräte: eigene CS-Leitung oder Kette

Für mehrere Geräte an einem Controller gibt es zwei Anordnungen.

Links: drei Geräte an gemeinsamen Leitungen SCK, MOSI und MISO mit je einer eigenen CS-Leitung vom Controller (3 + n Leitungen für n Geräte); rechts: Kette aus drei ICs, MOSI vom Controller an DIN von IC 1, DOUT jeweils an DIN des nächsten ICs, SCK und CS (LOAD) gemeinsam (mit KI erstellt)

Eigene CS-Leitung je Gerät ist der Normalfall: SCK, MOSI und MISO sind gemeinsam, jedes Gerät bekommt eine eigene Auswahlleitung. Für n Geräte brauchst Du 3 + n Signalleitungen. Jedes Gerät lässt sich einzeln und mit eigenem Takt und Modus ansprechen. Gehen die freien Pins aus, kann ein Decoder wie der 74HC138 aus drei Pins acht CS-Leitungen machen.

Kette (Daisy Chain): Manche Bausteine haben einen Datenausgang, an dem das hinausgeschobene Bit wieder erscheint – beim MAX7219 heißt er DOUT, beim Schieberegister 74HC595 QH’. Hängt man mehrere solcher Bausteine hintereinander, wirken sie wie ein einziges langes Schieberegister. Alle teilen sich SCK und eine CS-Leitung. Für drei kaskadierte MAX7219 schiebt der Controller drei 16-Bit-Wörter hintereinander durch die Kette – das Wort für den letzten Baustein zuerst – und erzeugt dann eine steigende Flanke an CS (beim MAX7219 LOAD genannt). Alle Bausteine übernehmen gleichzeitig. So steuern vier Leitungen beliebig viele LED-Matrizen. Der Preis: Auch wenn sich nur ein Baustein ändern soll, muss die ganze Kette neu beschrieben werden (die übrigen erhalten einen Leerbefehl, beim MAX7219 das Register 0x00, No-Op).

Nachrichtenaufbau und SPI-Modi

SPI selbst kennt nur den Rahmen einer Übertragung: CS fällt, eine Anzahl Takte überträgt Bits in beide Richtungen, CS steigt. Wie viele Bits es sind und was sie bedeuten, legt der Baustein fest. Vorher müssen Controller und Gerät aber eine Frage klären: An welcher Taktflanke werden die Daten gelesen?

CPOL und CPHA: die vier SPI-Modi

Zwei Einstellungen beschreiben das Taktverhalten:

  • CPOL (Clock Polarity): der Ruhepegel von SCK. CPOL = 0: SCK ruht auf LOW; CPOL = 1: SCK ruht auf HIGH.

  • CPHA (Clock Phase): an welcher Flanke abgetastet wird. CPHA = 0: an der ersten Flanke nach dem Fallen von CS, die Daten liegen also schon vor dem ersten Takt an; CPHA = 1: an der zweiten Flanke.

Daraus ergeben sich vier Modi. An der jeweils anderen Flanke legt der Sender das nächste Bit an.

Die vier SPI-Modi
Modus CPOL CPHA SCK in Ruhe Abtasten bei Daten wechseln bei
0 0 0 LOW steigender Flanke fallender Flanke
1 0 1 LOW fallender Flanke steigender Flanke
2 1 0 HIGH fallender Flanke steigender Flanke
3 1 1 HIGH steigender Flanke fallender Flanke
Impulsdiagramme der vier SPI-Modi mit CS, SCK und Daten: Modus 0 und 3 tasten bei steigender, Modus 1 und 2 bei fallender SCK-Flanke ab; Ruhepegel von SCK Low bei CPOL 0, High bei CPOL 1 (mit KI erstellt)

Modus 0 ist am weitesten verbreitet, viele Bausteine beherrschen zusätzlich Modus 3, weil beide an der steigenden Flanke abtasten. Welcher Modus gilt, steht im Datenblatt – manchmal ausdrücklich („SPI mode 0 and 3“), manchmal nur als Impulsdiagramm, aus dem Du Ruhepegel von SCK und Abtastflanke ablesen musst. Einige Beispiele:

SPI-Modi und Takte einiger Bausteine (laut Datenblatt bzw. SD-Spezifikation)
Baustein Funktion SPI-Modus höchster Takt
BME280 Druck, Temperatur, Feuchte 0 und 3 10 MHz
MAX7219 LED-Treiber, 16-Bit-Wörter 0 10 MHz
ADXL345 Beschleunigungssensor 3 5 MHz
SD-Karte Speicher (im SPI-Betrieb) 0 25 MHz

Stimmt der Modus nicht, liest der Empfänger jedes Bit an der falschen Flanke. Typisch sind dann um ein Bit verschobene Werte oder Daten, die nur manchmal stimmen.

Beispiel: Ein Register des BME280 lesen und schreiben

Der Klimasensor BME280 lässt sich über I²C und über SPI betreiben. Über SPI ist ein Registerzugriff besonders schlank. Das erste Byte nach dem Fallen von CS ist ein Steuerbyte: Bit 7 gibt die Richtung an (1 = Lesen, 0 = Schreiben), die Bits 6 bis 0 enthalten die Registeradresse ohne ihr höchstwertiges Bit.

  • Lesen: Für die Chip-ID im Register 0xD0 sendet der Controller 0xD0 (Bit 7 ist bereits 1) und danach ein Dummy-Byte. Während des Dummy-Bytes schiebt der Sensor den Registerinhalt 0x60 über MISO heraus. Weitere Takte liefern die folgenden Register; der Registerzeiger zählt automatisch hoch.

  • Schreiben: Für das Register 0xF4 (ctrl_meas) sendet der Controller das Steuerbyte 0x74 (Bit 7 auf 0 gesetzt) und danach das Datenbyte.

Impulsdiagramm SPI-Modus 0: CS fällt, 16 Takte auf SCK; MOSI überträgt 0xD0 (Bit 7 = 1 für Lesen plus Registeradresse), danach ein beliebiges Dummy-Byte; MISO wird im ersten Byte nicht ausgewertet und liefert im zweiten Byte 0x60, die Chip-ID des BME280; CS steigt (mit KI erstellt)

Eine Besonderheit des BME280 zeigt, wie unterschiedlich Bausteine SPI auslegen: Er wählt die Schnittstelle selbst. Liegt sein CSB-Pin beim Einschalten fest an der Versorgung, arbeitet er als I²C-Baustein. Sobald CSB einmal auf LOW gezogen wird, schaltet er auf SPI um und bleibt dabei bis zum nächsten Aus- und Einschalten.

Beispiel: 16-Bit-Wörter für den MAX7219

Der LED-Treiber MAX7219 erwartet 16-Bit-Wörter, höchstwertiges Bit zuerst: Die Bits D11 bis D8 enthalten die Registeradresse (z. B. 0x01 bis 0x08 für die Zeilen einer Matrix, 0x0F für den Displaytest), die Bits D7 bis D0 die Daten, D15 bis D12 werden ignoriert. Der Controller sendet also zwei Bytes, Adresse und Daten, und erzeugt danach eine steigende Flanke an LOAD (CS). Wie man das Protokoll mit einzelnen Pins nachbildet, zeigt der Artikel Mein erster Grafiktreiber: Dot-Matrix am Arduino; im Praxisteil unten erledigt das die SPI-Bibliothek.

Geschwindigkeit und Reichweite

Den höchsten Takt bestimmt das langsamste Glied: der Baustein (Datenblatt), der Mikrocontroller und die Verdrahtung.

SPI-Takte der Mikrocontroller
Mikrocontroller höchster SPI-Takt (Hardware) Hinweis
Arduino Uno (ATmega328P) 8 MHz (halber Prozessortakt) SPISettings rundet auf den nächstkleineren erreichbaren Takt ab
ESP8266 bis 80 MHz über die SPI-Hardware an festen Pins
ESP32 bis 80 MHz an den direkt verbundenen Standardpins; über die frei wählbare GPIO-Matrix deutlich weniger

Weil SPI ohne Adressen und ohne Bestätigung auskommt, ist der Verwaltungsaufwand gering. Der BME280 liefert seine acht Rohmessbytes über SPI mit einem Steuerbyte und acht Datenbytes:

t = \frac{9 \cdot 8\ \text{Takte}}{10\ \mathrm{MHz}} = 7{,}2\ \mathrm{\mu s}

Über I²C mit 400 kHz dauert derselbe Zugriff rund 0,26 ms (Rechnung im Artikel zu I²C), also etwa 35-mal so lange. Noch deutlicher wird der Unterschied beim Display aus der Einleitung: Ein Bild mit 240 \cdot 240 Pixeln zu je 16 Bit sind 921 600 Bit. Bei 40 MHz SPI-Takt dauert die Übertragung rund 23 ms, was etwa 40 Bilder je Sekunde erlaubt; über I²C mit 400 kHz wären es mehr als 2 Sekunden je Bild.

Reichweite: Die steilen Flanken, die SPI schnell machen, begrenzen die Leitungslänge. Bei Takten im MHz-Bereich führen schon einige Dezimeter Leitung zu Reflexionen und Übersprechen; besonders empfindlich ist SCK, weil jede Störflanke als zusätzlicher Takt zählt. Für längere Verbindungen senkst Du den Takt, hältst die Leitungen kurz und führst neben SCK eine Masseleitung mit. Kleine Serienwiderstände (z. B. 33 bis 100 Ω) direkt am treibenden Ausgang dämpfen Reflexionen. Für Strecken über mehrere Meter ist SPI nicht gedacht.

Varianten: Einige Bausteine sparen eine Leitung und nutzen eine gemeinsame Datenleitung für beide Richtungen (3-Draht-SPI, beim BME280 über ein Konfigurationsbit wählbar). Flash-Speicher verwenden Dual- und Quad-SPI mit zwei bzw. vier Datenleitungen, um den Durchsatz zu vervielfachen. Auch ESP8266 und ESP32 lesen ihr Programm so aus dem externen Flash – die Pins GPIO6 bis GPIO11 sind dafür belegt und für eigene Schaltungen tabu.

Praxis: SPI an Arduino, ESP8266 und ESP32

Die Arduino-Bibliothek SPI gehört bei allen drei Plattformen zum Lieferumfang. Wo die Leitungen anzuschließen sind, zeigt das Tabset; weitere Pinbelegungen findest Du im Artikel zu den Pinouts von ESP8266 und ESP32. Die CS-Leitung kannst Du bei allen drei frei wählen.

ESP32 (DevKit mit ESP32-WROOM): Logikpegel 3,3 V, Pins nicht 5-V-fest. Für eigene Geräte stehen zwei SPI-Controller zur Verfügung, VSPI (Standard, Objekt SPI) und HSPI.

SPI-Standardpins am ESP32
Signal VSPI (Standard) HSPI
SCK GPIO18 GPIO14
MISO GPIO19 GPIO12
MOSI GPIO23 GPIO13
CS GPIO5 GPIO15

GPIO5, GPIO12 und GPIO15 sind Konfigurations-Pins (Strapping-Pins), die der ESP32 beim Start auswertet. Ist GPIO12 beim Booten HIGH, startet er nicht. Andere ESP32-Varianten (S2, S3, C3) haben andere Standardpins.

#include <SPI.h>

const int PIN_CS = 5;

void setup() {
  Serial.begin(115200);
  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_CS, HIGH);   // Gerät zunächst abgewählt
  SPI.begin();                  // VSPI: SCK 18, MISO 19, MOSI 23
  // eigene Pins: SPI.begin(SCK, MISO, MOSI, SS);
  // zweiter Bus: SPIClass *hspi = new SPIClass(HSPI); hspi->begin();
}

Transaktionen: Takt, Bitreihenfolge und Modus

Weil jedes Gerät seinen eigenen Takt und Modus haben kann, fasst die SPI-Bibliothek jeden Zugriff in eine Transaktion: SPI.beginTransaction() stellt Takt, Bitreihenfolge und Modus für das Gerät ein, dann ziehst Du dessen CS-Leitung auf LOW, überträgst mit SPI.transfer() und gibst CS und Bus wieder frei. Damit lesen und schreiben wir die Register des BME280 aus dem Abschnitt Nachrichtenaufbau:

SPISettings bmeSpi(1000000, MSBFIRST, SPI_MODE0);   // 1 MHz, MSB zuerst, Modus 0

byte leseRegister(byte reg) {
  SPI.beginTransaction(bmeSpi);
  digitalWrite(PIN_CS, LOW);        // Gerät auswählen
  SPI.transfer(reg | 0x80);         // Steuerbyte: Bit 7 = 1 (Lesen)
  byte wert = SPI.transfer(0x00);   // Dummy-Byte senden, Registerinhalt empfangen
  digitalWrite(PIN_CS, HIGH);       // Gerät abwählen
  SPI.endTransaction();
  return wert;
}

void schreibeRegister(byte reg, byte wert) {
  SPI.beginTransaction(bmeSpi);
  digitalWrite(PIN_CS, LOW);
  SPI.transfer(reg & 0x7F);         // Steuerbyte: Bit 7 = 0 (Schreiben), z. B. 0xF4 -> 0x74
  SPI.transfer(wert);
  digitalWrite(PIN_CS, HIGH);
  SPI.endTransaction();
}

// in setup() nach SPI.begin():
//   Serial.println(leseRegister(0xD0), HEX);   // 60 = BME280

Für den MAX7219 sieht ein Zugriff fast gleich aus, nur mit 16-Bit-Wörtern und der Übernahme an der steigenden LOAD-Flanke:

const int PIN_LOAD = 10;            // CS des MAX7219

void max7219Senden(byte registerAdresse, byte daten) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  digitalWrite(PIN_LOAD, LOW);
  SPI.transfer(registerAdresse);    // D15..D8: Registeradresse in D11..D8
  SPI.transfer(daten);              // D7..D0
  digitalWrite(PIN_LOAD, HIGH);     // steigende Flanke: MAX7219 übernimmt das Wort
  SPI.endTransaction();
}

// max7219Senden(0x0F, 0x01);       // Displaytest ein: alle LEDs leuchten
// max7219Senden(0x0F, 0x00);       // Displaytest aus

Für den Alltag gibt es auch hier Bibliotheken. Die Adafruit BME280 Library arbeitet über SPI, wenn Du dem Konstruktor die CS-Leitung übergibst: Adafruit_BME280 bme(PIN_CS); und danach bme.begin();. Für LED-Matrizen mit MAX7219 gibt es z. B. die Bibliotheken LedControl und MD_MAX72XX.

Den Bus beobachten: Logic-Analyzer

Mit einem Logic-Analyzer an CS, SCK, MOSI und MISO und dem SPI-Dekoder von PulseView siehst Du jedes übertragene Byte in beide Richtungen. Zwei Einstellungen sind wichtig: Im Dekoder müssen CPOL, CPHA und die Bitreihenfolge zum Gerät passen, und als Trigger eignet sich die fallende Flanke von CS, mit der jede Übertragung beginnt. Die Abtastrate muss ein Mehrfaches des SPI-Takts betragen; günstige Logic-Analyzer mit 24 MHz Abtastrate reichen daher nur für SPI-Takte bis etwa 2 bis 4 MHz. Zum Messen stellst Du den Takt im Sketch vorübergehend herunter. Die Bedienung beschreibt der Artikel Digitale Signale mit PulseView und einem Logic-Analyzer untersuchen.

Checkliste: Bevor Du einen Sensor oder Aktor anschließt

Bevor ein neues SPI-Modul an den Mikrocontroller kommt, prüfst Du im Datenblatt des Bausteins bzw. Moduls und in der Dokumentation der Bibliothek die folgenden Punkte.

Checkliste vor dem Anschluss eines SPI-Bausteins
Prüffrage Worauf Du bei SPI achtest Beispiel
Hardware (Datenblatt)
Welche Schnittstelle nutzt der Baustein? SPI, I²C oder beides; wie wird gewählt? Wie heißen die Pins (SDI/SDO, DIN/DOUT …)? Gibt es überhaupt einen MISO-Ausgang? Der BME280 schaltet bei der ersten fallenden Flanke an CSB auf SPI; viele TFT-Displays haben kein MISO.
Kann ich einen weiteren Teilnehmer anschließen? freier Pin für CS (Konfigurations-Pins meiden), gibt das Gerät MISO frei, wenn CS HIGH ist? Lässt es sich in eine Kette hängen? Ein microSD-Modul, das MISO nicht freigibt, blockiert alle anderen Geräte am Bus.
Liegen Versorgungsspannung und Leistung vor? Spannungsbereich von Chip und Modul, Stromaufnahme aller Geräte zusammenzählen, Stromspitzen beachten Eine LED-Matrix mit MAX7219 braucht bei voller Helligkeit mehrere 100 mA aus der 5-V-Versorgung – nicht über einen GPIO-Pin, sondern direkt aus dem Netzteil.
Sind die Logikpegel kompatibel? V_\mathrm{IH}/V_\mathrm{IL} des Geräts, 5-V-Festigkeit der MCU-Pins; schnelle unidirektionale Pegelwandler MAX7219 an 3,3 V: HIGH erst ab 3,5 V zugesichert, also 74AHCT125 einsetzen.
Ist die Taktfrequenz kompatibel? höchster SPI-Takt und SPI-Modus des Geräts, Bitreihenfolge, Wortlänge BME280: Modus 0 oder 3, höchstens 10 MHz; ADXL345: Modus 3, höchstens 5 MHz.
Passen die Umgebungsbedingungen? Betriebstemperatur, Feuchte, Schutzart (IP), Leitungslänge und Störquellen in der Nähe von SCK Ein Display im Außengehäuse braucht einen geeigneten Temperaturbereich; lange Flachbandkabel erfordern einen niedrigeren Takt.
Software (Bibliotheksdokumentation)
Welche Bibliothek eignet sich für MCU und Anwendung? unterstützte Architekturen, Hardware- oder Software-SPI, Pflege, Lizenz, Abhängigkeiten, Funktionsumfang Für TFT-Displays ist z. B. TFT_eSPI auf ESP32 optimiert, Adafruit GFX läuft auf mehr Plattformen.
Reicht der Speicher des Mikrocontrollers? Programmspeicher (Flash), Arbeitsspeicher (RAM) für Bildpuffer, Schriften und Dateisystem Die SD-Bibliothek braucht auf dem Uno einen Puffer von 512 Byte – ein Viertel seines Arbeitsspeichers.
Sind Hardware und Software geprüft? Beispielsketche der Bibliothek, Testprogramme des Herstellers, Chip-ID oder Displaytest, Plausibilitätsprüfung Chip-ID des BME280 lesen (0x60); beim MAX7219 mit dem Displaytest-Register alle LEDs einschalten.

I²C oder SPI?

Viele Sensoren beherrschen beide Schnittstellen, und manche Projekte nutzen beide gleichzeitig. Die Gegenüberstellung hilft bei der Wahl:

I²C und SPI im Vergleich
Merkmal I²C SPI
Signalleitungen für 4 Geräte 2 (SDA, SCL) 7 (SCK, MOSI, MISO, 4 × CS)
Richtung halbduplex vollduplex
Auswahl der Geräte 7-Bit-Adresse im Telegramm eigene CS-Leitung
Bestätigung ACK/NACK nach jedem Byte keine
Ausgangsstufen Open-Drain mit Pull-ups Gegentakt
typischer Takt 100 kHz, 400 kHz 1 bis 80 MHz
Verwaltungsaufwand Adressbytes, ACK-Bits, Start und Stopp nahezu keiner
Stärken wenige Pins, viele Geräte, Fehler sofort erkennbar Durchsatz, Einfachheit der Hardware, große Datenmengen
typische Geräte Sensoren, Echtzeituhren, kleine Displays, Port-Erweiterungen Farbdisplays, SD-Karten, Flash-Speicher, A/D-Wandler, Funkmodule

Als Faustregel: I²C, wenn viele langsame Teilnehmer an wenigen Pins hängen sollen und es auf Millisekunden nicht ankommt. SPI, wenn große Datenmengen fließen (Displays, Speicher), schnell abgetastet werden muss oder Pins kein Engpass sind. Bei einem Sensor wie dem BME280, der beides kann, ist I²C meist die bequemere Wahl; über SPI lohnt er sich, wenn die I²C-Adressen ausgehen oder der I²C-Bus durch andere Geräte schon ausgelastet ist.

Fehlersuche: Wenn nur Nullen kommen

Weil SPI keine Bestätigung kennt, äußern sich Fehler oft nur in falschen Werten. Prüfe von der Hardware zur Software: Versorgung und Masse, Verdrahtung, CS, Modus und Takt.

Typische Fehlerbilder bei SPI
Fehlerbild mögliche Ursache So prüfst Du
es kommt nur 0x00 oder 0xFF zurück MISO nicht verbunden oder falscher Pin, CS wird nicht LOW, Gerät nicht versorgt, Gerät im I²C-Betrieb Verdrahtung und CS-Pin im Code prüfen; Logic-Analyzer an CS und MISO
Werte sind um ein Bit verschoben oder nur manchmal richtig falscher SPI-Modus, Takt zu hoch, falsche Bitreihenfolge Modus und höchsten Takt im Datenblatt nachsehen; Takt testweise auf 100 kHz senken
ein Gerät allein funktioniert, zwei zusammen nicht ein Gerät gibt MISO nicht frei, CS-Leitungen beim Start undefiniert, Geräte mit verschiedenen Modi ohne Transaktionen jedes Gerät einzeln testen; Pull-ups an CS; beginTransaction() für jedes Gerät
Mikrocontroller startet nicht mehr Konfigurations-Pin belegt (ESP32 GPIO12 HIGH, ESP8266 GPIO15 mit Pull-up) oder Flash-Pins GPIO6 bis GPIO11 verwendet Gerät abziehen und neu starten; andere Pins wählen
Arduino Uno hängt in SPI-Funktionen D10 als Eingang geschaltet und LOW: SPI-Hardware im Slave-Modus D10 als Ausgang schalten
Fehler bei längeren Leitungen Reflexionen und Übersprechen auf SCK, fehlende Masseverbindung Leitungen kürzen, Takt senken, Masse neben SCK führen, Serienwiderstände

Leitfragen

  1. Welche Leitungen hat SPI, und welche Kennzeichen unterscheiden SPI von I²C?

SPI nutzt den Takt SCK, die Datenleitungen MOSI (Controller → Gerät) und MISO (Gerät → Controller) sowie je Gerät eine low-aktive CS-Leitung, dazu eine gemeinsame Masse. SPI ist synchron und vollduplex, arbeitet mit Gegentaktausgängen und Takten im MHz-Bereich, kennt aber weder Adressen noch Bestätigungen. Siehe Abschnitt „Steckbrief“

  1. Warum ist SPI vollduplex, und warum muss der Controller senden, um zu lesen?

Controller und Gerät bilden einen Ring aus zwei Schieberegistern: Mit jedem Takt wandert ein Bit über MOSI hinaus und gleichzeitig eines über MISO zurück. Takte erzeugt nur der Controller, und nur beim Senden – deshalb schiebt er zum Lesen ein Dummy-Byte hinaus. Siehe Abschnitt „Leitungen und Potenziale“

  1. Warum muss ein nicht ausgewähltes Gerät seinen MISO-Ausgang hochohmig schalten, und wozu dient ein Pull-up an CS?

SPI-Ausgänge sind Gegentaktausgänge; auf MISO hängen alle Geräte, und zwei aktive Ausgänge würden gegeneinander treiben. Ein Gerät mit CS HIGH muss MISO deshalb freigeben. Der Pull-up an CS hält Geräte abgewählt, solange der Mikrocontroller startet und seine Pins noch undefiniert sind. Siehe Abschnitt „Leitungen und Potenziale“

  1. Was legen CPOL und CPHA fest, und woran erkennst Du den passenden SPI-Modus?

CPOL bestimmt den Ruhepegel von SCK, CPHA, ob an der ersten oder zweiten Flanke nach dem Fallen von CS abgetastet wird. Daraus ergeben sich die Modi 0 bis 3; Modus 0 (Ruhe LOW, Abtasten bei steigender Flanke) ist am häufigsten. Den Modus liest Du im Datenblatt ab, notfalls aus dem Impulsdiagramm. Siehe Abschnitt „Nachrichtenaufbau und SPI-Modi“

  1. Wie liest und schreibt der Controller ein Register eines SPI-Sensors wie des BME280?

CS auf LOW, dann ein Steuerbyte: Bit 7 gibt die Richtung an (1 = Lesen, 0 = Schreiben), die übrigen Bits die Registeradresse. Beim Lesen folgt ein Dummy-Byte, während dessen das Gerät den Registerinhalt über MISO sendet (Chip-ID: 0xD0 senden, 0x60 empfangen); beim Schreiben folgt das Datenbyte. Danach CS wieder HIGH. Siehe Abschnitt „Nachrichtenaufbau und SPI-Modi“

  1. Wie schließt Du mehrere SPI-Geräte an, und wie viele Leitungen brauchst Du dafür?

Im Normalfall teilen sich alle Geräte SCK, MOSI und MISO, und jedes bekommt eine eigene CS-Leitung: 3 + n Signalleitungen für n Geräte. Bausteine mit Datenausgang wie MAX7219 oder 74HC595 lassen sich zu einer Kette verbinden, die mit vier Leitungen auskommt, aber immer als Ganzes beschrieben wird. Siehe Abschnitt „Mehrere Geräte“

  1. Wann ist SPI, wann I²C die bessere Wahl?

SPI lohnt sich bei großen Datenmengen und hohen Abtastraten (Displays, SD-Karten, schnelle Wandler), weil es mit MHz-Takten ohne Verwaltungsaufwand arbeitet; dafür braucht es mehr Pins und erkennt Fehler nicht selbst. I²C eignet sich für viele langsame Teilnehmer an zwei Leitungen. Siehe Abschnitt „I²C oder SPI?“ und Abschnitt „Geschwindigkeit und Reichweite“

  1. Was prüfst Du, bevor Du einen SPI-Baustein an einen Mikrocontroller anschließt?

Im Datenblatt: Schnittstelle und Pinbezeichnungen, freier CS-Pin und Freigabe von MISO, Versorgung und Strombedarf, Logikpegel, SPI-Modus und höchster Takt sowie Umgebungsbedingungen. In der Bibliotheksdokumentation: passende Bibliothek, Speicherbedarf (Puffer!) und Beispiele oder Testprogramme des Herstellers. Siehe Abschnitt „Checkliste“


Hinweis zur Nachnutzung als Open Educational Resource (OER)

Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “SPI: Schnell, einfach, mit eigener Leitung für jedes Gerät” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/spi-bus veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/mcu/mcu-schnittstellen. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 03.11.2026.

[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: