Unterrichts- und Lernmaterial für Mikrocontroller
Unterrichts- und Lernmaterial fürMikrocontroller

SPI - Serial Peripheral Interface

SPI-Bus mit der BASIC Stamp wird im Kapitel Synchrone Kommunikation, Abschnitt 3, behandelt. In diesem Kapitel geht es um den Arduino UNO und AT-Mikrocontroller (ATtiny, ATmega) sowie den Programmiersprachen C und BASCOM.

Bussysteme verbinden verschiedene elektronische Bausteine, die miteinander kommunizieren müssen. Um den Verdrahtungsaufwand möglichst gering zu halten (Kosten), sollten so wenig Leitungen wie möglich verbaut werden. Aus dieser Grundüberlegung wurden in der Vergangenheit verschiedene serielle Zweidrahtbussysteme entwickelt, die für das Senden und Empfangen von Daten mit nur zwei Leitungen auskommen. Bekannte Vertreter sind der I2C- oder TWI-Bus und SPI (serial peripheral interface) oder Microwire.

In diesem Kapitel werden verschiedene SPI-Bausteine verwendet und gezeigt, wie das Protokoll aufgebaut ist, wie sie zu programmieren sind und was auf der Daten- und Taktleitung warum abläuft.

1 - Der SPI-Bus

Als Zweidrahtbussystem besteht ein SPI-Bus aus zwei Datenleitungen und einer Taktleitung, über die alle Teilnehmer am SPI-Bus angeschlossen sind; eine vierte Leitung dient als Auswahlleitung:

Bezeichner Erläuterung

SDO    oder

MOSI 

Serial Data Out, Datenausgang oder

Master Out - Slave In

SDI    oder

MISO

Serial Data In, Dateneingang oder

Master In - Slave Out

SCLK    oder

SCK
Serial Clock, Takt

SS    oder

CS   oder

STE

Slave Select      oder

Chip Select       oder

Slave Transmit Enable (seltener benutzt)

Die von mir verwendeten Bezeichner sind rot markiert.

In einem SPI-Bussystem gibt es genau einen Master, der das Taktsignal SCK erzeugt und über die zweite Leitung CS die Bausteine (Slaves) auswählt, mit denen er kommunizieren möchte.

Abbildung 1 - Master-Slave Kommunikation. Die Taktabfrage erfolgt hier bei aufsteigender Flanke.

Eine CS-Leitung ist low-aktiv, das heißt, wird sie auf GND gezogen, wird der mit dieser Leitung verbundene Slave aktiviert (Abb. 1). Seine Aufgabe besteht nun darin, am MOSI-Pin zu "lauschen" und seine Daten entsprechend dem Taktsignal am MISO-Pin auf den Bus zu legen. In Abb. 1 erfolgt die Taktabfrage bei steigender Flanke; ebenso möglich ist die Abfrage bei fallender Flanke.

Es gibt zwei technische Umsetzungsmöglichkeiten für eine CS-Leitung:

  1. alle Slaves teilen sich eine Leitung (Abb. 2).
  2. jeder Slave bekommt eine separate Leitung (Abb. 3).

Mit den beiden Steuerleitungen (CS, SCK), den zwei Datenleitungen (MOSI, MISO) und den Kabeln für die Versorgungsspannung (+5V, GND) werden maximal insgesamt sechs Leitungen benötigt.

Abbildung 2 - Alle Slaves sind über eine CS-Leitung miteinander verbunden.
Abbildung 3 - Jeder Slave ist über eine gesonderte CS-Leitung mit dem Master verbunden.

Über einen MISO-Eingang werden nicht nur Daten von einem Slave zurückgelesen; er kann auch als Datenausgang für ein nachgeschaltetes Slavegerät dienen (Abb. 2). Eine solche Anordnung wird auch als Daisy-Chain-Konfiguration oder Kaskadierung bezeichnet.  

Einige Eigenschaften des SPI-Busses

 

  • Das Gerät im Master-Modus gibt das Taktsignal vor und aktiviert über die CS-Leitung(en) die Bausteine, mit denen es kommunizieren möchte.
  • Nur ein Gerät kann auf einem SPI-Bus Master sein. Alle anderen Geräte sind Slaves.
  • Die Anzahl der Slaves wird begrenzt durch die Anzahl der CS-Leitungen.
  • CS und SCK werden beim Master als Ausgänge, beim Slave als Eingänge angesehen.
  • Der SPI-Bus arbeitet im Vollduplexbetrieb, das heißt, dass Daten gleichzeitig vom Master an den Slave und vom Slave an den Master übertragen werden können.
  • Es wird festgelegt, mit welcher Taktflanke (steigend oder fallend) eingelesen bzw. ausgelesen wird.
  • Es wird festgelegt, ob das MSB (most significant bit) oder das LSB zuerst übertragen wird.
  • Die Taktfrequenz geht bis in den MHz-Bereich.

2 - Die SPI-Modi

Motorola, die Entwicklungsfirma von SPI, hat keine Spezifikation zu Protokollen der Datenübertragung veröffentlicht und nicht festgeschrieben, ob Daten bei fallender oder steigender Taktflanke, bei CS low active oder high active übernommen werden sollen. Dadurch haben sich vier SPI Modi (Betriebsarten) entwickelt, die über die Parameter CPOL (Clock Polarität) und CPHA (Clock Phase) beschrieben werden.

SPI-Modus CPOL CPHA
0 0 0
1 0 1
2 1 0
3 1 1

Bei einer Phasenlage CPHA = 0 und einer Taktpolarität CPOL = 0 findet eine Datenübernahme bei steigender Taktflanke und CS = 0 statt; entsprechend bei CPOL = 1 mit fallender Taktflanke. Bei CPHA = 1 verhält es sich genau umgekehrt. Die folgende Tabelle gibt eine Übersicht.

CPOL CPHA Datenübernahme bei ...
0 0 steigender Taktflanke
0 1 fallender Taktflanke
1 0 fallender Taktflanke
1 1 steigender Taktflanke

Wie sich die vier Modi im Zeitdiagramm unterscheiden, zeigen die folgenden beiden Abbildungen.

Abbildung 4 - Die Modi CPOL = 0, CPHA = 0 und CPOL = 0, CPHA = 1
Abbildung 5 - Die Modi CPOL = 1, CPHA = 0 und CPOL = 1, CPHA = 1

Bleibt noch nachzutragen, dass mit acht Taktzyklen ein Byte übertragen wird. Die Übertragung mehrerer Datenbytes hintereinander ist erlaubt; sie endet, sobald die CS-Leitung wieder auf HIGH gesetzt wird.

Nach soviel Theorie kommen wir jetzt zu einer ersten Übung, in der man sich mit dem oben Gesagten vertraut macht und im Realexperiment die Theorie überprüft.

Übung 1 - 74HC595 und SPI Bus

In dieser Übung steuert ein Arduino UNO über den SPI-Bus ein 8-Bit Schieberegister vom Typ 74HC595 an, dessen acht Ausgängen je einer LED mit Vorwiderstand verbunden sind.

Übung 1 - 74HC595 und SPI Bus

Material
  • 1x  Arduino UNO
  • 8x  LED, rot
  • 1x  74HC595, 8-Bit Schieberegister
  • 8x  Widerstand, 330 Ohm
  • 1x  Steckbrett
  • diverse Steckdrähte
Aufgaben
  • Baue die Schaltung nach Schaltplan auf einem Steckbrett auf und verbinde sie mit dem Arduino UNO.
  • Verbinde den Arduino UNO über ein USB-Kabel mit einem PC.
  • Übertrage das Programm spi_74hc595_1.ino in den Editor und speichere es ab.
  • Starte das Programm.

Pinbelegung des 74HC595

Die Bedeutung der Pinabkürzungen
GND Masseanschluss
/OE Output enable (Ausgang aktivieren)
QA - QH' Ausgänge
RCLK RCLK Eingang (Speicherregister Takt)
SER serieller Eingang
SRCLK SRCLK Eingang (Schieberegister Takt)
/SRCLR /SRCLR Eingang
Vcc Betriebsspannung

Der 74HC595 besteht aus einem Schiebe- und einem Ausgangsregister, die separat getaktet werden. In das Schieberegister werden acht Bits seriell eingelesen. Ist der Vorgang abgeschlossen, werden die Daten über einen entsprechenden Speichertakt an ein Ausgangsregister (Latch) übergeben. Die Datenübergabe erfolgt mit der steigenden Flanke.

Arduino UNO, 74HC595 und acht LEDs verbinden

Tabelle 1 - Verbindungen zwischen Arduino UNO und 74HC595

Der Schaltungsaufbau

Das Programm spi_74hc595_1.ino

Wie arbeitet das Programm spi_74hc595_1.ino?

Zeilen 11 - 13

Die Anschlüsse am Arduino UNO werden festgelegt (Tab. 1).  

 

Zeilen 18 - 20

Die digitalen Anschlüsse 4, 5 und 6 am Arduino werden als Ausgänge initialisiert.

 

Zeilen 21 - 26

Die Schleife wird acht mal durchlaufen. Bei jedem Durchlauf wird

1. der Schiebetakt auf LOW gesetzt

2. die Bitinformation im Array led_muster[i] an der Stelle i ausgelesen

3. der Schiebetakt auf HIGH gesetzt und die Bitinformation ins Register übernommen.

 

Zeile 27ff

Der Speichertakt wird auf HIGH gesetzt und damit der Inhalt des Schieberegisters ins Latch verschoben. Die im Schieberegister eingelesenen acht Bits stehen jetzt am Ausgang des 74HC595 zur Verfügung und werden über die nach Masse geschalteten LEDs optisch angezeigt. Ein HIGH am Latch-Ausgang bedeutet, die angeschlossene LED leuchtet.

Bit-Banging

Für diese Übung wurden weder die Harwarepins genutzt, die der Arduino UNO für SPI zur Verfügung stellt, noch wurde auf die Befehle der Arduino Bibliothek SPI.h zurückgegriffen. Wir haben die I/O Pins ausschließlich mit den Funktionen

  • digitalRead()
  • digitalWrite()

angesprochen. Eine solche Methode nennt man auch Bit-Banging des SPI Protokolls. Sie ist zum Beispiel immer dann notwendig, wenn für ein Bauteil vom Hersteller SPI-Befehlslängen von mehr als 8-Bit gefordert werden.

Übung 2 - 7-Segment-Anzeige und SPI

Der Arduino UNO stellt speziell für das SPI Protokoll dedizierte Pinanschlüsse zur Verfügung (Tab. 2). In dieser Übung wird eine 7-Segment-Anzeige über einen SPI-Bus angesteuert und für das Programm wird die SPI-Bibliothek und ihre Funktionen genutzt.

Tabelle 2 - SPI-Anschlüsse am Arduino UNO und ihre Verbindung mit einem 74HC595 Baustein.

Übung 2 - 7-Segment-Anzeige und SPI Bus

Material

 

  • 1x  Arduino UNO
  • 1x  7-Segment-Anzeige (z.B. SA52-11HWA von Kingsbright)
  • 1x  74HC595, 8-Bit Schieberegister
  • 8x  Widerstand, 330 Ohm
  • 1x  Steckbrett
  • diverse Steckdrähte

 

Aufgaben

 

  • Baue die Schaltung nach Vorgabe der Schaltskizze auf und verbinde das Steckbrett mit dem Arduino UNO.
  • Übertrage das Programm spi_74hc595_7SegmentAnzeige.ino in den Editor und speichere es ab.
  • Verbinde das Arduinoboard über ein USB-Kabel mit einem Rechner und starte das Programm.
  • Überprüfe, ob auf der Anzeige die Zahl 3 erscheint.
  • Wie muss das Programm verändert werden, damit die Zahl 4 angezeigt wird?

 

Schaltskizze

Abbildung 6 - 74HC595 und 7-Segment-Anzeige werden auf einem Steckbrett aufgebaut und anschließend mit dem Arduino UNO verbunden (blaue Anschlussleitungen). Die Spannungsversorgung wird ebenfalls vom Arduino Board übernommen (5V und GND).

Das Programm spi_74hc595_7SegmentAnzeige.ino

Bevor es an die Besprechung des Programms geht, ist auffällig, wie wenig Programmzeilen benötigt werden, um eine 7-Segment-Anzeige anzusprechen. Dafür verantwortlich sind die in der Bibliothek SPI.h abgelegten Programmfunktionen, auf die jetzt zugegriffen werden kann.

In dieser Übung werden vier Funktionen benutzt:

  • SPI.begin()
  • SPI.beginTransaction()
  • SPI.transfer()
  • SPI.end()
  • SPI.begin()
  • initialisiert den SPI-Bus; SCK, MOSI und CS werden als Ausgang deklariert. SCK und MOSI werden anschließend auf LOW und CS auf HIGH gezogen.
  • SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPIMODE0)
  • initialisiert den SPI-Bus mit den SPIsettings: Geschwindigkeit des Schiebetaktes, SPI-Modus und MSB oder LSB zuerst. Die max. Taktgeschwindigkeit bei einem 74HC595 ist >20 MHz; hier wurde ein Wert von 1 MHz gewählt.
  • SPI.transfer
  • überträgt ein Byte Daten über den SPI-Bus zum Slave und empfängt gleichzeitig Daten vom Slave, falls gefordert. Dazu muss eine Zuweisung erfolgen:
  • empfangeneDaten = SPI.transfer(sendeDaten)
  • (siehe auch unter Reference bei Arduino.cc.
  • SPI.end()
  • beendet den SPI Bus.

Wie arbeitet das Programm spi_74hc595_7SegmentAnzeige.ino?

Zeilen 10 - 11

Die Datei SPI.h wird in das Programm eingebunden und eine Variable zahl als integer-Variable definiert mit gleichzeitiger Wertzuweisung.

 

Zeilen 13 - 19

Die Methode setup() startet mit der Funktion SPI.begin() und beendet den Initialisierungsprozess des SPI Busses mit dem Aufruf von SPI.beginTransaction().

An das 7-Segment-Display wird die Bitfolge 0b10010010 übertragen, die auf dem Display die Zahl 3 darstellt.

Die Darstellung auf dem Display hängt von der Bedrahtung zwischen Schieberegister und 7-Segment-Display ab. Im meinem Fall gilt:

Dabei werden die Segmente in der Reihenfolge:

  • f - a - b - dp - c - d - e - g

abgerufen. Wenn also die Segmente a, b, c, d und g eingeschaltet werden müssen, um die Zahl 3 darzustellen, dann entspricht das in meinem Fall der Bitfolge:

  • 0 - 1 - 1 - 0 - 1 - 1 - 0 - 1

Nicht genug damit. Die LEDs der Anzeige haben eine gemeinsame Anode; sie beginnen genau dann zu leuchten, wenn der Ausgang des Latch auf 0 gezogen wird. Die Bitfolge 0b01101100 muss deshalb invertiert werden und lautet neu

  • 0b10010010

das entspricht der Hexadezimalzahl

  • 0x92

und dieser Wert wurde der Variablen zahl im Programm zugewiesen.

Weiterführende Übungen zur Vertiefung

  • Mit welchem Wert der Variablen zahl wird auf dem Display eine 9 ausgegeben?
  • Wie muss das Programm umgeschrieben werden, damit alle Zahlen von 0 bis 9 nacheinander im Sekundentakt angezeigt werden?

Im zweiten Teil von SPI besser verstehen geht es um die Ansteuerung eines AT-Mikrocontrollers unter BASCOM. Welche Befehle stehen für den SPI-Bus in dieser Sprache zur Verfügung und wie werden sie eingesetzt. Dazu gibt es wieder Übungen zum Ausprobieren.

Interessiert? Dann geht es hier weiter zum SPI besser verstehen - Teil 2.

Lösungen

  • Die Zahl 4 wird durch die Variable zahl = 0x56 und die Zahl 9 durch die Variable zahl = 0x12 auf der 7-Segment-Anzeige dargestellt.

Kommentar schreiben

Kommentare

  • olaf (Sonntag, 10. Dezember 2017 08:35)

    wow...die mit Abstand beste Site, die ich bisher zu diesem Thema gesehen habe :-))
    Vielen Dank dafür. Hilft super beim Erklären!!

  • David Eisenblätter (Sonntag, 11. Februar 2018 13:38)

    Sehr schön erklärt, und zufällig heute, wo ich nochmal nach einer detailierten Gedankenstütze diesbezüglich gesucht habe!

    Vielen vielen Dank!

    David.

Bitte geben Sie den Code ein
* Pflichtfelder
Druckversion Druckversion | Sitemap
© Reinhard Rahner - Gettorf