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.
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).
| 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
LOWzieht. 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
0x00oder0xFF– 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.
| 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.
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:
LOWheiß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
HIGHerkennt 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.
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 aufHIGH.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.
| 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 |
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:
| 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 Registerinhalt0x60ü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.
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.
| 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.
| 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 = BME280Fü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 ausFü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.
| 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:
| 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.
| 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
- 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“
- 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“
- 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“
- 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“
- 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“
- 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“
- 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“
- 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“
Links und weitere Informationen
oer-informatik.de: I²C – Ein Bus, zwei Leitungen, viele Sensoren
oer-informatik.de: Mein erster Grafiktreiber – Dot-Matrix am Arduino
oer-informatik.de: Digitale Signale mit PulseView und einem Logic-Analyzer untersuchen
oer-informatik.de: Schnittstellen und Datenübertragung – Wiederholung und Übungsaufgaben
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]
