class SPI – протокол шины последовательного периферийного интерфейса (Serial Peripheral Interface, сторона контроллера)

SPI – это синхронный последовательный протокол, управляемый контроллером. На физическом уровне шина состоит из 3 линий: SCK, MOSI, MISO. Несколько устройств могут использовать одну и ту же шину. Каждое устройство должно иметь отдельный, 4-й сигнал, CS (Chip Select), чтобы выбрать конкретное устройство на шине, с которым происходит обмен данными. Управление сигналом CS должно осуществляться в пользовательском коде (через класс machine.Pin).

Существуют как аппаратная, так и программная реализации SPI через классы SPI и SoftSPI. Аппаратный SPI использует базовую аппаратную поддержку системы для выполнения чтения/записи и обычно эффективен и быстр, но может иметь ограничения на то, какие выводы можно использовать. Программный SPI реализован методом bit-banging и может использоваться на любом выводе, но не столь эффективен. Эти классы имеют одинаковый набор методов и различаются в основном способом конструирования.

Пример использования:

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.

Конструкторы

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)

Создаёт объект SPI на заданной шине, id. Значения id зависят от конкретного порта и его аппаратной части. Значения 0, 1 и т. д. обычно используются для выбора аппаратного блока SPI №0, №1 и т. д.

Без дополнительных параметров объект SPI создаётся, но не инициализируется (он использует настройки от последней инициализации шины, если таковая была). Если переданы дополнительные аргументы, шина инициализируется. См. init для параметров инициализации.

Методы

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

Инициализирует шину SPI с заданными параметрами:

  • baudrate – частота тактового сигнала SCK.

  • polarity может быть 0 или 1 и задаёт уровень, на котором находится тактовая линия в состоянии покоя.

  • phase может быть 0 или 1 для выборки данных по первому или второму фронту тактового сигнала соответственно.

  • bits – ширина каждой передачи в битах. Только значение 8 гарантированно поддерживается всем оборудованием.

  • firstbit может быть SPI.MSB или SPI.LSB.

  • sck, mosi, miso – объекты выводов (machine.Pin), используемые для сигналов шины. Для большинства аппаратных блоков SPI (выбираемых параметром id конструктора) выводы фиксированы и не могут быть изменены. В некоторых случаях аппаратные блоки допускают 2-3 альтернативных набора выводов для аппаратного блока SPI. Произвольное назначение выводов возможно только для программного драйвера SPI на основе bit-banging (id = -1).

В случае аппаратного SPI фактическая тактовая частота может быть ниже запрошенной скорости передачи. Это зависит от аппаратной платформы. Фактическую частоту можно определить, распечатав объект SPI.

deinit() None

Выключает шину SPI.

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

Читает количество байт, заданное nbytes, непрерывно записывая при этом один байт, заданный write. Возвращает объект bytes с прочитанными данными.

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

Читает в буфер, заданный buf, непрерывно записывая при этом один байт, заданный write. Возвращает None.

write(buf: bytes) None

Записывает байты, содержащиеся в buf. Возвращает None.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Записывает байты из write_buf, одновременно читая в read_buf. Буферы могут быть одним и тем же или разными, но оба буфера должны иметь одинаковую длину. Возвращает None.

Константы

MSB: int

Передайте в firstbit для передачи/приёма старшего бита первым (наиболее распространённый порядок).

LSB: int

Передайте в firstbit для передачи/приёма младшего бита первым.

class SoftSPI – программно эмулируемая шина SPI

Класс SoftSPI реализует SPI методом bit-banging на произвольных выводах GPIO. Он предоставляет тот же набор методов, что и SPI, поэтому существующий код, ориентированный на аппаратный SPI, может перейти на программный, изменив только конструктор. Используйте его, когда нужные вам выводы не подключены к аппаратному блоку SPI, когда вам нужно больше шин, чем доступно аппаратно, или когда периферийное устройство требует нестандартной фазировки тактового сигнала, которую аппаратура не может выдать.

Конструкторы

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)

Создаёт объект программного SPI. sck, mosi и miso должны быть указаны – неявного выбора выводов нет. См. SPI.init() для значения остальных параметров. Стандартное значение baudrate ниже, чем для аппаратного SPI, поскольку цикл bit-bang имеет больше накладных расходов.

Методы

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

Заново инициализирует программную шину SPI с заданными параметрами. Обновляются только переданные аргументы; остальные сохраняют свои предыдущие значения. См. SPI.init() для значения каждого аргумента.

deinit() None

Освобождает выводы GPIO, захваченные драйвером bit-bang, и прекращает управление шиной.

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

Читает nbytes байт, непрерывно записывая при этом один байт write. Возвращает объект bytes, содержащий принятые данные.

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

Читает в buf, непрерывно записывая при этом один байт write. Возвращает None.

write(buf: bytes) None

Записывает buf на шину. Принятые байты отбрасываются.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Одновременно записывает write_buf и читает в read_buf. Оба буфера должны иметь одинаковую длину; они могут совпадать.

Константы

MSB: int

Передайте в firstbit для передачи/приёма старшего бита первым.

LSB: int

Передайте в firstbit для передачи/приёма младшего бита первым.