Das serielle Peripherie Interface (SPI) erlaubt high-speed synchronen Datentransfer zwischen dem ATmega8 und peripheren Bausteinen oder zwischen zwei seriellen AVR Bausteinen. Das SPI des ATmega8 hat folgende Eigenschaften:
- Voll-Duplex, Drei Draht synchroner Datentransfer
- Master oder Slave Operation
- LSB oder MSB als ersten Datentransfer
- Sieben programmierbare Bitraten
- Interrupt bei Ende der Übertragung
- Schreibkollision Schutz Flag
- Aufwachen aus dem Idle-Mode
- Master SPI Modus mit doppelter Geschwindigkeit (CK/2)
SPI Blockdiagramm
Die Zusammenarbeit zwischen Master und Slave CPUs wird in nachfolgenden Bild dargestellt. Das System besteht aus zwei Schieberegistern und einem Master Taktgenerator. Der SPI Master initiiert einen Kommunikationszyklus, indem der den Slave Select SS Pin 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 (MOSI) Leitung geschoben und vom Slave zum Master über die Master in Slave out (MISO) Leitung. 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 Data Register 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 Interrupt Enable Bit (SPIE) im SPCR Register 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 (SS) Leitung auf High-Pegel zieht. Das zuletzt eingegangene Byte verbleibt im Buffer Register und kann dort abgeholt werden.
Wenn der Baustein als Slave konfiguriert ist, schläft das SPI Interface mit MISO im tristate bis die SS Leitung auf High gezogen wird. Dann kann die Software die Daten im SPI Data Register SPDR aktualisieren, 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 Flag (SPIF) gesetzt. Wenn das SPI Interrupt Enable Bit (SPIE) im SPCR Register gesetzt ist, wird dann ein Interrupt ausgeführt. Der Slave kann weitere Daten in das SPDR senden, bevor die eingegangenen Daten gelesen wurden. Das zuletzt eingegangene Byte verbleibt im Buffer Register und kann dort abgeholt werden.
Master-Slave Zusammenarbeit
Das System ist in Senderichtung einfach gebuffert und in Empfangsrichtung zweifach gebuffert. Das bedeutet, dass ein zu übertragenes Byte erst dann in das SPI Data Register 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 SPI 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 MOSI, MISO, SCK und SS Pins wie folgt dar:
SPI Pinfunktionen
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.
SPI Code Beispiel 1
Das folgende Beispiel zeigt das Initialisieren der SPI als Slave und einen einfachen Empfang von Daten.
SPI Code Beispiel 2