Synchroner, vollduplexfähiger Datentransfer mit drei Leitungen
Master- oder Slave-Funktion: Taktgeber oder Fremdtaktung
Datentransfer mit tiefstwertigem oder höchstwertigem Bit beginnend auswählbar
Sieben programmierbare Bitraten
Interrupt bei Ende der Übertragung
Schutz vor Schreibkollision
Aufwachen aus dem Idle-Mode
Master-SPI-Modus mit doppelter Geschwindigkeit (CK/2)
19.2 Überblick
Das serielle Peripherie-Interface (SPI) realisiert synchronen Datentransfer
mit hoher Geschwindigkeit zwischen dem Controller
und peripheren Bausteinen oder zwischen zwei AVR-Mikrocontrollern.
Die Zusammenarbeit zwischen Master- und Slave-CPUs wird im Bild 19-2 dargestellt.
Das System besteht aus zwei Schieberegistern und einem Master-Taktgenerator.
Der SPI-Master initiiert einen Kommunikationszyklus,
indem der den SS-Pin (Slave Select) des gewünschten Slaves auf Low-Pegel zieht.
Der Master und der Slave bereiten die zu übertragenden Daten in ihren entsprechenden Schieberegistern vor
und der Master generiert die erforderlichen Taktpulse auf der SCK-Leitung, damit die Daten ausgetauscht werden.
Die Daten werden vom Master zum Slave immer über die „Master out Slave in“-Leitung (MOSI) geschoben
und vom Slave zum Master über die „Master in Slave out“-Leitung (MISO).
Nach jedem übertragenen Datenpaket synchronisiert der Master den Slave,
indem die „Slave Select“-Leitung (SS) auf High-Potential legt.
Wenn der Baustein als Master konfiguriert ist, so hat das SPI keine automatische Kontrolle über die SS-Leitung.
Sie muss durch die Software gesteuert werden um eine Kommunikation zu starten.
Wenn dies geschehen ist, startet das Schreiben eines Bytes in das SPI-Datenregister SPDR den SPI-Taktgenerator
und die Hardware schiebt die acht Bits in den Slave.
Nachdem die acht Bits geschoben wurden, stoppt der SPI-Taktgenerator
und das End of Transmission Flag (SPIF) wird gesetzt.
Wenn das SPI-Interruptfreigabe-Bit (SPIE) im Register SPCR gesetzt ist,
wird dann ein Interrupt ausgeführt.
Der Master kann dann die Kommunikation fortsetzen,
indem er ein weiteres Byte in das SPDR-Register schreibt.
Oder er beendet die Kommunikation, indem er die „Slave Select“-Leitung (SS) auf High-Pegel zieht.
Das zuletzt eingegangene Byte verbleibt im Puffer-Register und kann dort abgeholt werden.
Wenn der Baustein als Slave konfiguriert ist,
schläft das SPI-Interface mit MISO im hochohmigen Zustand, solagne die SS-Leitung auf High gehalten wird.
Die Software kann Daten in das SPI-Datenregister SPDR schreiben,
allerdings werden die Daten nicht durch die am SCK-Pin eingehenden Takte ausgeschoben,
bis der SS Pin auf Low gelegt wurde.
Wenn ein Byte komplett geschoben wurde, wird das „End of Transmission“-Bit (SPIF) gesetzt.
Wenn das SPI-Interruptfreigabebit (SPIE) im SPCR-Register gesetzt ist, wird ein Interrupt ausgeführt.
Der Slave kann weitere Daten in SPDR schreiben, bevor die eingegangenen Daten gelesen wurden.
Das zuletzt eingegangene Byte verbleibt im Puffer-Register und kann dort abgeholt werden.
Bild 19-2: Zusammenarbeit Master und Slave
Das System ist in Senderichtung einfach und in Empfangsrichtung zweifach gepuffert.
Das bedeutet, dass ein zu übertragenes Byte
erst dann in das SPI-Datenregister geschrieben werden kann,
wenn eine laufende Übertragung komplett angeschlossen ist.
Beim Empfangen von Daten muss ein empfangenes Byte gelesen werden,
bevor die Übertragung des folgenden Bytes abgeschlossen ist.
Andernfalls geht das zuerst empfangene Byte verloren.
Im Slave-Modus tastet die Kontrolllogik das ankommende Signal am SCK-Pin ab.
Um ein korrektes Abtasten zu gewährleisten,
sollte die Frequenz des SCK-Taktes nicht größer sein als fOSC/4.
Wenn das SPI freigegeben ist, stellt sich die Datenrichtung
der Pins MOSI, MISO, SCK und SS wie folgt ein:
Tabelle 19-1: SPI Pinfunktionen
Pin
Richtung als SPI-Master
Richtung als SPI-Slave
MOSI
benutzerdefiniert
Eingang
MISO
Eingang
benutzerdefiniert
SCK
benutzerdefiniert
Eingang
SS
benutzerdefiniert
Eingang
Das nachfolgende Beispiel zeigt das Initialisieren des SPI als Master und eine einfache Datenübertragung.
DDR_SPI aus dem Beispiel muss durch das aktuelle Datenrichtungsregister ersetzt werden, das die SPI-Pins kontrolliert.
DD_MOSI, DD_MISO und DD_SCK muss ersetzt werden durch die aktuellen Datenrichtungsbits für diese Pins.
Beispiel: Wenn MOSI an Pin PB5 liegt, dann DD_MOSI durch DDB5 ersetzen und DDR_SPI durch DDRB.
Kodebeispiel in Assembler
:
; Setze MOSI und SCK als Ausgang, alles andere als Eingangldi r17,(1<<DD_MOSI)|(1<<DD_SCK)
out DDR_SPI,r17
; SPI-Master freigeben, Taktfrequenz = fck/16ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
out SPCR,r17
ret
: ; Starte Daten-Senden (r16)out SPDR,r16
: ; Warte bis Senden fertigin r16, SPSR
sbrs r16, SPIF
rjmp Wait_Transmit
ret
Kodebeispiel in C
void SPI_MasterInit(void) {
/* Setze MOSI und SCK als Ausgang, alles andere als Eingang */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* SPI-Master freigeben, Taktfrequenz = fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData) {
/* Starte Daten-Senden */
SPDR = cData;
/* Warte bis Senden fertig */while (!(SPSR & (1<<SPIF)));
}
Das folgende Beispiel zeigt das Initialisieren des SPI als Slave und einen einfachen Empfang von Daten.
Kodebeispiel in Assembler
:
; Setze MISO als Ausgang, alles andere als Eingangldi r17,(1<<DD_MISO)
out DDR_SPI,r17
ldi r17,(1<<SPE)
out SPCR,r17 ; SPI freigebenret
: ; Warte bis Empfang fertigin r16, SPSR
sbrs r16, SPIF
rjmp SPI_SlaveReceive
in r16,SPDR ; Lese empfangenes Datenbyteret
Kodebeispiel in C
void SPI_SlaveInit(void) {
/* Setze MISO als Ausgang, alles andere als Eingang */
DDR_SPI = (1<<DD_MISO);
/* SPI freigeben */
SPCR = (1<<SPE);
}
char SPI_SlaveReceive(void) {
/* Warte bis Empfang fertig */while (!(SPSR & (1<<SPIF)));
/* Lese empfangenes Datenbyte */return SPDR;
}
19.3 SS-Pinfunktion
Nachfolgend wird die Funktion des SS-Pins in den verschiedenen Betriebsmodi beschrieben.
19.3.1 Slave-Modus
Wenn das SPI als Slave konfiguriert ist, ist das SS-Pin immer ein Eingang.
Wenn SS auf Low gehalten wird, wird das SPI aktiviert und MISO wird zum Ausgang,
wenn er durch den Anwender so konfiguriert wurde.
Alle anderen Pins sind Eingänge.
Wenn SS auf High gelegt wird, werden alle Pins Eingänge und das SPI wird deaktiviert,
d.h. es kann keine Daten mehr empfangen.
Man beachte, dass die SPI-Logik zurückgesetzt wird, wenn das SS-Pin auf High gelegt wird.
Das SS-Pin ist hilfreich für die Paket- oder Bytesynchronisation
indem der Slave-Bitzähler synchron mit dem Master-Taktgenerator gehalten wird.
Wenn das SS-Pin auf High liegt,
setzt der SPI-Slave die Sende- und Empfangslogik zurück und verwirft alle teilweise empfangenen Daten.
19.3.2 Master-Modus
Wenn das SPI als Master konfiguriert ist (MSTR im SPCR gesetzt), kann der Anwender die Richtung des SS-Pins bestimmen.
Wenn SS als Ausgang konfiguriert ist, ist es ein allgemeines Ausgangspin, der die Funktion des SPI nicht beeinflusst.
Gewöhnlich wird das Pin mit dem SS-Pin eines Slaves verbunden.
Wenn SS als Eingang konfiguriert ist, muss es auf High gehalten werden, um die Masterfunktion sicherzustellen.
Wenn das SS-Pin durch die Peripherie auf Low gezogen wird, während SPI als Master mit SS-Pin als Eingang konfiguriert ist,
wird das SPI-System dies so interpretieren, als sei sie von einem anderen Master
als Slave angesprochen worden und damit beginnen, Daten an den vermeintlichen Master zu senden.
Um Buskollisionen zu vermeiden, führt das SPI-System dann folgende Aktionen durch:
Das MSTR-Bit im SPCR-Register wird gelöscht, folglich wird das SPI-System zum Slave.
Damit werden die Pins MOSI und SCK zu Eingängen
Das SPIF-Flag im SPSR wird gesetzt,
und wenn der SPI-Interrupt freigegeben ist — und das I-Bit im SREG gesetzt ist — wird die Interruptroutine ausgeführt.
Wenn also eine interruptgesteuerte SPI-Übertragung im Mastermodus verwendet wird und die Möglichkeit besteht,
dass das SS-Pin auf Low gezogen wird, so muss die Interruptroutine immer überprüfen, ob das MSTR-Bit noch gesetzt ist.
Wenn das MSTR-Bit durch einen externen Slave Select gelöscht wurde, so muss es durch die Software wieder gesetzt werden,
um den SPI Mastermodus zu reaktivieren.
19.4 Datenmodi
Es gibt vier verschiedene Kombinationen der SCK-Phase und -Polarität mit Bezug auf die seriellen Daten,
die durch die CPHA- und CPOL-Bits festgelegt werden.
Das Format des SPI-Datentransfers ist in den Timingdiagrammen dargestellt.
Die Datenbits werden mit entgegengesetzten Flanken von SCK geschoben und übernommen,
damit ausreichend Zeit für die Stabilisierung des Daten bleibt.
Dies wird aus folgender Tabelle deutlich.
Tabelle 19-2: SPI-Datenmodi
Datenmodus
Bedingung
Erste Flanke
Zweite Flanke
0
CPOL=0, CPHA=0
abtasten (steigend)
setzen (fallend)
1
CPOL=0, CPAH=1
setzen (steigend)
abtasten (fallend)
2
CPOL=1, CPHA=0
abtasten (fallend)
setzen (steigend)
3
CPOL=1, CPHA=1
setzen (fallend)
abtasten (steigend)
Bild 19-3: SPI-Übertragung mit CPHA=0
Bild 19-4: SPI-Übertragung mit CPHA=1
19.5 Register-Beschreibung
19.5.1 SPCR — Kontrollregister
Bit
7
6
5
4
3
2
1
0
(0x4C)
SPIE
SPE
DORD
MSTR
CPOL
CPHA
SPR1
SPR0
SPCR
Zugriff
R/W
R/W
R/W
R/W
R/W
R/W
R/W
R/W
Startwert
0
0
0
0
0
0
0
0
Bit 7 — SPIE: SPI Interrupt Enable
Wenn dieses Bit mit einer 1 beschrieben wird, ist der SPI-Interrupt freigegeben.
Der Interrupt wird ausgeführt, wenn das I-Bit im SREG gesetzt ist und das SPIF Flag im SPSR Register gesetzt wird.
Bit 6 — SPE: SPI Enable
Wenn dieses Bit mit einer 1 beschrieben wird, ist das SPI freigegeben.
Es muss gesetzt werden um alle SPI-Operationen freizugeben.
Bit 5 — DORD: Data Order
Wenn dieses Bit mit einer 1 beschrieben ist, werden die Daten mit dem LSB voran übertragen.
Wenn dieses Bit gelöscht ist, werden die Daten mit dem MSB voran übertragen.
Bit 4 — MSTR: Master / Slave Select
Wenn dieses Bit mit einer 1 beschrieben ist, ist der Mastermodus ausgewählt, wenn es gelöscht ist, arbeitet die SPI im Slave-Modus.
Wenn SS als Eingang konfiguriert ist und im Mastermodus auf Low gezogen wird, wird das MSTR-Bit gelöscht und SPIF im SPSR wird gesetzt.
Der Anwender muss dann das MSTR-Bit wieder setzen um den Mastermodus zu reaktivieren.
Bit 3 — CPOL: Clock Polatity
Wenn dieses Bit mit einer 1 beschrieben ist, ist SCK auf High, wenn er nicht benutzt wird.
Ist das Bit gelöscht, so ist SCK auf Low, wenn er nicht benutzt wird.
Siehe Timingdiagramme.
Zusammengefasst ist die CPOL Funktion wie folgt:
Tabelle 19-3: CPOL-Funktion
CPOL
Vorderflanke
Rückflanke
0
steigend
fallend
1
fallend
steigend
Bit 2 — CPHA: Clock Phase
Dieses Bit legt fest, ob die Daten mit der Vorder- oder Rückflanke von SCK abgetastet werden.
Siehe Timingdiagramme.
Zusammengefasst ist die CPHA-Funktion wie folgt:
Tabelle 19-4: CPHA-Funktion
CPHA
Vorderflanke
Rückflanke
0
abtasten
setzen
1
setzen
abtasten
Bit 1, 0 — SPR1, SPR0: SPI Clock Rate Select 1 und 0
Dieses beiden Bits kontrollieren die Taktrate an SCK des Bausteins, wenn er im Mastermodus arbeitet.
SPR1 und SPR0 haben keine Auswirkungen im Slavemodus.
Die Beziehung zwischen SCK und der Oszillator Taktfrequenz fOSC ist nachfolgend dargestellt:
Tabelle 19-5: Beziehung zwischen SCK und Oszillatorfrequenz
SPI2X
SPR1
SPR0
SCK-Frequenz
0
0
0
fOSC/4
0
0
1
fOSC/16
0
1
0
fOSC/64
0
1
1
fOSC/128
1
0
0
fOSC/2
1
0
1
fOSC/8
1
1
0
fOSC/32
1
1
1
fOSC/64
Das SPI2X-Bit befindet sich im SPI-Statusregister (SPSR)
19.5.2 SPSR — Statusregister
Bit
7
6
5
4
3
2
1
0
(0x4D)
SPIF
WCOL
-
-
-
-
-
SPI2X
SPSR
Zugriff
R
R
R
R
R
R
R
R/W
Startwert
0
0
0
0
0
0
0
0
Bit 7 — SPIF: SPI Interrupt Flag
Wenn eine serielle Übertragung komplett ist, wird dieses Bit gesetzt.
Ein Interrupt wird ausgeführt, wenn SPIE in SPCR gesetzt ist und die Interrupts global freigegeben sind.
Wenn SS im Mastermodus als Eingang definiert ist und auf Low gezogen wird, wird das Flag ebenfalls gesetzt.
Das SPIF wird durch die Hardware automatisch gelöscht, wenn die dazugehörige Interruptroutine ausgeführt wird.
Alternativ kann das Flag auch gelöscht werden,
wenn zunächst das SPI-Statusregister mit gesetztem SPIF gelesen wird
und danach ein Zugriff auf das SPI-Datenregister (SPDR) erfolgt.
Bit 6 — WCOL: Write Collision Flag
Das WCOL-Bit wird gesetzt, wenn in das SPI-Datenregister während einer laufenden Übertragung geschrieben wird.
Das WCOL-Bit (und SPIF) werden gelöscht,
wenn zunächst das SPI-Statusregister mit gesetztem WCOL gelesen wird
und danach ein Zugriff auf das SPI-Datenregister (SPDR) erfolgt.
Bit 5:1 — reserviert
Diese Bits sind reserviert und werden immer als 0 gelesen.
Bit 0 — SPI2X: Double SPI Speed Bit
Wenn dieses Bit gesetzt wird, verdoppelt sich die Taktfrequenz SCK, wenn SPI im Mastermodus betrieben wird.
Das bedeutet, dass die maximale SCK-Frequenz halb so groß wie die Frequenz des CPU-Taktes sein kann.
Wenn SPI im Slave-Modus arbeitet,
ist das korrekte Arbeiten allerdings nur mit einer Frequenz kleiner fOSC/4 garantiert.
19.5.3 SPDR — Datenregister
Bit
7
6
5
4
3
2
1
0
(0x4E)
MSB
LSB
SPDR
Zugriff
R/W
R/W
R/W
R/W
R/W
R/W
R/W
R/W
Startwert
X
X
X
X
X
X
X
X
undefiniert
Das SPI Data Register ist ein Schreib/Lese-Register,
das für den Datenaustausch zwischen den Registern und dem SPI Schieberegister verwendet wird.
Das Schreiben in das Register startet eine Datenübertragung.
Beim Lesen wird auf einen Eingangspuffer des Schieberegisters zugegriffen.