class SPI – ein Serial-Peripheral-Interface-Busprotokoll (Controller-Seite)

SPI ist ein synchrones serielles Protokoll, das von einem Controller gesteuert wird. Auf physischer Ebene besteht ein Bus aus 3 Leitungen: SCK, MOSI, MISO. Mehrere Geräte können sich denselben Bus teilen. Jedes Gerät sollte über ein separates, viertes Signal verfügen, CS (Chip Select), um ein bestimmtes Gerät auf einem Bus auszuwählen, mit dem die Kommunikation stattfindet. Die Verwaltung eines CS-Signals sollte im Benutzercode erfolgen (über die Klasse machine.Pin).

Es existieren sowohl Hardware- als auch Software-SPI-Implementierungen über die Klassen SPI und SoftSPI. Hardware-SPI nutzt die zugrunde liegende Hardwareunterstützung des Systems zum Ausführen der Lese-/Schreibvorgänge und ist in der Regel effizient und schnell, kann aber Einschränkungen hinsichtlich der verwendbaren Pins haben. Software-SPI wird durch Bit-Banging implementiert und kann an jedem Pin verwendet werden, ist aber nicht so effizient. Diese Klassen verfügen über dieselben Methoden und unterscheiden sich hauptsächlich in der Art ihrer Konstruktion.

Anwendungsbeispiel:

from machine import SPI, Pin

spi = SPI(0, baudrate=400000)           # Create SPI peripheral 0 at frequency of 400kHz.
                                        # Depending on the use case, extra parameters may be required
                                        # to select the bus characteristics and/or pins to use.
cs = Pin(4, mode=Pin.OUT, value=1)      # Create chip-select on pin 4.

try:
    cs(0)                               # Select peripheral.
    spi.write(b"12345678")              # Write 8 bytes, and don't care about received data.
finally:
    cs(1)                               # Deselect peripheral.

try:
    cs(0)                               # Select peripheral.
    rxdata = spi.read(8, 0x42)          # Read 8 bytes while writing 0x42 for each byte.
finally:
    cs(1)                               # Deselect peripheral.

rxdata = bytearray(8)
try:
    cs(0)                               # Select peripheral.
    spi.readinto(rxdata, 0x42)          # Read 8 bytes inplace while writing 0x42 for each byte.
finally:
    cs(1)                               # Deselect peripheral.

txdata = b"12345678"
rxdata = bytearray(len(txdata))
try:
    cs(0)                               # Select peripheral.
    spi.write_readinto(txdata, rxdata)  # Simultaneously write and read bytes.
finally:
    cs(1)                               # Deselect peripheral.

Konstruktoren

class machine.SPI(id: int, baudrate: int = 1000000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None)

Erzeugt ein SPI-Objekt auf dem angegebenen Bus, id. Die Werte von id hängen vom jeweiligen Port und seiner Hardware ab. Die Werte 0, 1 usw. werden üblicherweise verwendet, um den Hardware-SPI-Block #0, #1 usw. auszuwählen.

Ohne zusätzliche Parameter wird das SPI-Objekt erstellt, aber nicht initialisiert (es übernimmt die Einstellungen der letzten Initialisierung des Busses, sofern vorhanden). Werden zusätzliche Argumente angegeben, wird der Bus initialisiert. Siehe init für die Initialisierungsparameter.

Methoden

init(baudrate: int = 1000000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = SPI.MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None) None

Initialisiert den SPI-Bus mit den angegebenen Parametern:

  • baudrate ist die SCK-Taktrate.

  • polarity kann 0 oder 1 sein und gibt den Pegel an, auf dem die Taktleitung im Ruhezustand liegt.

  • phase kann 0 oder 1 sein, um Daten an der ersten bzw. zweiten Taktflanke abzutasten.

  • bits ist die Breite jeder Übertragung in Bit. Nur 8 wird garantiert von jeder Hardware unterstützt.

  • firstbit kann SPI.MSB oder SPI.LSB sein.

  • sck, mosi, miso sind Pin-Objekte (machine.Pin), die für die Bussignale verwendet werden. Bei den meisten Hardware-SPI-Blöcken (wie durch den Parameter id des Konstruktors ausgewählt) sind die Pins fest und können nicht geändert werden. In einigen Fällen erlauben Hardwareblöcke 2-3 alternative Pin-Sätze für einen Hardware-SPI-Block. Beliebige Pin-Zuweisungen sind nur bei einem Bitbanging-SPI-Treiber möglich (id = -1).

Im Fall von Hardware-SPI kann die tatsächliche Taktfrequenz niedriger sein als die angeforderte baudrate. Dies hängt von der Plattform-Hardware ab. Die tatsächliche Rate kann durch Ausgeben des SPI-Objekts ermittelt werden.

deinit() None

Schaltet den SPI-Bus aus.

read(nbytes: int, write: int = 0x00) bytes

Liest eine durch nbytes angegebene Anzahl von Bytes, während kontinuierlich das einzelne durch write angegebene Byte geschrieben wird. Gibt ein bytes-Objekt mit den gelesenen Daten zurück.

readinto(buf: bytearray, write: int = 0x00) None

Liest in den durch buf angegebenen Puffer, während kontinuierlich das einzelne durch write angegebene Byte geschrieben wird. Gibt None zurück.

write(buf: bytes) None

Schreibt die in buf enthaltenen Bytes. Gibt None zurück.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Schreibt die Bytes aus write_buf und liest gleichzeitig in read_buf. Die Puffer können identisch oder verschieden sein, aber beide Puffer müssen dieselbe Länge haben. Gibt None zurück.

Konstanten

MSB: int

An firstbit übergeben, um zuerst das höchstwertige Bit zu senden/empfangen (die gebräuchlichste Reihenfolge).

LSB: int

An firstbit übergeben, um zuerst das niederwertigste Bit zu senden/empfangen.

class SoftSPI – softwareemulierter SPI-Bus

Die Klasse SoftSPI implementiert SPI durch Bit-Banging beliebiger GPIO-Pins. Sie stellt dieselbe Methodenoberfläche wie SPI bereit, sodass bestehender Code, der auf Hardware-SPI abzielt, mit nur einer Änderung am Konstruktor auf Software umsteigen kann. Verwenden Sie sie, wenn die benötigten Pins nicht mit einem Hardware-SPI-Block verdrahtet sind, wenn Sie mehr als die verfügbaren Hardwarebusse benötigen oder wenn ein Peripheriegerät eine nicht standardmäßige Taktphasierung erfordert, die die Hardware nicht erzeugen kann.

Konstruktoren

class machine.SoftSPI(baudrate: int = 500000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None)

Erzeugt ein Software-SPI-Objekt. sck, mosi und miso müssen angegeben werden – es gibt keine implizite Pin-Auswahl. Siehe SPI.init() für die Bedeutung der übrigen Parameter. Die Standard-baudrate ist niedriger als bei Hardware-SPI, da die Bit-Bang-Schleife mehr Overhead hat.

Methoden

init(baudrate: int = 500000, *, polarity: int = 0, phase: int = 0, bits: int = 8, firstbit: int = SoftSPI.MSB, sck: Pin | None = None, mosi: Pin | None = None, miso: Pin | None = None) None

Initialisiert den Software-SPI-Bus mit den angegebenen Parametern neu. Nur die angegebenen Argumente werden aktualisiert; die übrigen behalten ihre vorherigen Werte. Siehe SPI.init() für die Bedeutung jedes Arguments.

deinit() None

Gibt die vom Bit-Bang-Treiber belegten GPIO-Pins frei und beendet die Ansteuerung des Busses.

read(nbytes: int, write: int = 0x00) bytes

Liest nbytes Byte, während kontinuierlich das einzelne Byte write geschrieben wird. Gibt ein bytes-Objekt mit den empfangenen Daten zurück.

readinto(buf: bytearray, write: int = 0x00) None

Liest in buf, während kontinuierlich das einzelne Byte write geschrieben wird. Gibt None zurück.

write(buf: bytes) None

Schreibt buf auf den Bus. Empfangene Bytes werden verworfen.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Schreibt write_buf und liest gleichzeitig in read_buf. Beide Puffer müssen dieselbe Länge haben; sie dürfen sich überlappen.

Konstanten

MSB: int

An firstbit übergeben, um zuerst das höchstwertige Bit zu senden/empfangen.

LSB: int

An firstbit übergeben, um zuerst das niederwertigste Bit zu senden/empfangen.