klasa SPI – protokół magistrali Serial Peripheral Interface (strona kontrolera)

SPI to synchroniczny protokół szeregowy sterowany przez kontroler. Na poziomie fizycznym magistrala składa się z 3 linii: SCK, MOSI, MISO. Wiele urządzeń może współdzielić tę samą magistralę. Każde urządzenie powinno mieć osobny, czwarty sygnał, CS (Chip Select), aby wybrać konkretne urządzenie na magistrali, z którym odbywa się komunikacja. Zarządzanie sygnałem CS powinno odbywać się w kodzie użytkownika (za pomocą klasy machine.Pin).

Istnieją zarówno sprzętowe, jak i programowe implementacje SPI poprzez klasy SPI i SoftSPI. Sprzętowe SPI wykorzystuje sprzętowe wsparcie systemu do wykonywania odczytów/zapisów i jest zwykle wydajne i szybkie, ale może mieć ograniczenia co do tego, które piny mogą być używane. Programowe SPI jest realizowane metodą bit-bangingu i może być używane na dowolnym pinie, ale nie jest tak wydajne. Klasy te mają dostępne te same metody i różnią się głównie sposobem konstruowania.

Przykład użycia:

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.

Konstruktory

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)

Konstruuje obiekt SPI na danej magistrali, id. Wartości id zależą od konkretnego portu i jego sprzętu. Wartości 0, 1 itd. są powszechnie używane do wyboru sprzętowego bloku SPI #0, #1 itd.

Bez dodatkowych parametrów obiekt SPI jest tworzony, ale nie inicjalizowany (ma ustawienia z ostatniej inicjalizacji magistrali, jeśli taka miała miejsce). Jeśli podano dodatkowe argumenty, magistrala jest inicjalizowana. Zobacz init, aby poznać parametry inicjalizacji.

Metody

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

Inicjalizuje magistralę SPI z podanymi parametrami:

  • baudrate to częstotliwość zegara SCK.

  • polarity może wynosić 0 lub 1 i jest poziomem, na którym znajduje się bezczynna linia zegara.

  • phase może wynosić 0 lub 1, aby próbkować dane odpowiednio na pierwszym lub drugim zboczu zegara.

  • bits to szerokość każdego transferu w bitach. Tylko wartość 8 jest gwarantowana jako obsługiwana przez cały sprzęt.

  • firstbit może wynosić SPI.MSB lub SPI.LSB.

  • sck, mosi, miso to obiekty pinów (machine.Pin) używane jako sygnały magistrali. W przypadku większości sprzętowych bloków SPI (wybieranych parametrem id konstruktora) piny są stałe i nie można ich zmienić. W niektórych przypadkach bloki sprzętowe pozwalają na 2-3 alternatywne zestawy pinów dla sprzętowego bloku SPI. Dowolne przypisania pinów są możliwe tylko dla sterownika SPI realizowanego metodą bit-bangingu (id = -1).

W przypadku sprzętowego SPI rzeczywista częstotliwość zegara może być niższa niż żądana wartość baudrate. Zależy to od sprzętu platformy. Rzeczywistą szybkość można ustalić, drukując obiekt SPI.

deinit() None

Wyłącza magistralę SPI.

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

Odczytuje liczbę bajtów określoną przez nbytes, jednocześnie zapisując nieprzerwanie pojedynczy bajt podany przez write. Zwraca obiekt bytes z odczytanymi danymi.

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

Odczytuje do bufora określonego przez buf, jednocześnie zapisując nieprzerwanie pojedynczy bajt podany przez write. Zwraca None.

write(buf: bytes) None

Zapisuje bajty zawarte w buf. Zwraca None.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Zapisuje bajty z write_buf, jednocześnie odczytując do read_buf. Bufory mogą być takie same lub różne, ale oba bufory muszą mieć tę samą długość. Zwraca None.

Stałe

MSB: int

Przekaż do firstbit, aby nadawać/odbierać najpierw najbardziej znaczący bit (najczęstsza kolejność).

LSB: int

Przekaż do firstbit, aby nadawać/odbierać najpierw najmniej znaczący bit.

klasa SoftSPI – magistrala SPI emulowana programowo

Klasa SoftSPI implementuje SPI poprzez bit-banging dowolnych pinów GPIO. Udostępnia ten sam zestaw metod co SPI, dzięki czemu istniejący kod przeznaczony dla sprzętowego SPI może przejść na programowe jedynie zmieniając konstruktor. Używaj jej, gdy potrzebne piny nie są podłączone do sprzętowego bloku SPI, gdy potrzebujesz więcej magistral niż dostępne sprzętowo, lub gdy urządzenie peryferyjne wymaga niestandardowego fazowania zegara, którego sprzęt nie potrafi wytworzyć.

Konstruktory

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)

Konstruuje programowy obiekt SPI. sck, mosi i miso muszą zostać podane – nie ma niejawnego wyboru pinów. Zobacz SPI.init(), aby poznać znaczenie pozostałych parametrów. Domyślny baudrate jest niższy niż dla sprzętowego SPI, ponieważ pętla bit-bang ma większy narzut.

Metody

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

Ponownie inicjalizuje programową magistralę SPI z podanymi parametrami. Aktualizowane są tylko podane argumenty; pozostałe zachowują swoje poprzednie wartości. Zobacz SPI.init(), aby poznać znaczenie każdego argumentu.

deinit() None

Zwalnia piny GPIO zajęte przez sterownik bit-bang i przestaje sterować magistralą.

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

Odczytuje nbytes bajtów, jednocześnie zapisując nieprzerwanie pojedynczy bajt write. Zwraca obiekt bytes zawierający odebrane dane.

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

Odczytuje do buf, jednocześnie zapisując nieprzerwanie pojedynczy bajt write. Zwraca None.

write(buf: bytes) None

Zapisuje buf na magistralę. Odebrane bajty są odrzucane.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Jednocześnie zapisuje write_buf i odczytuje do read_buf. Oba bufory muszą mieć tę samą długość; mogą się pokrywać.

Stałe

MSB: int

Przekaż do firstbit, aby nadawać/odbierać najpierw najbardziej znaczący bit.

LSB: int

Przekaż do firstbit, aby nadawać/odbierać najpierw najmniej znaczący bit.