class SPI – un protocolo de bus de interfaz periférica serie (lado del controlador)

SPI es un protocolo serie síncrono gobernado por un controlador. A nivel físico, un bus consta de 3 líneas: SCK, MOSI, MISO. Varios dispositivos pueden compartir el mismo bus. Cada dispositivo debería tener una cuarta señal separada, CS (Chip Select), para seleccionar un dispositivo concreto en un bus con el que se realiza la comunicación. La gestión de una señal CS debe ocurrir en el código de usuario (mediante la clase machine.Pin).

Existen implementaciones de SPI tanto por hardware como por software mediante las clases SPI y SoftSPI. El SPI por hardware utiliza el soporte de hardware subyacente del sistema para realizar las lecturas/escrituras y suele ser eficiente y rápido, pero puede tener restricciones sobre qué pines pueden usarse. El SPI por software se implementa mediante bit-banging y puede usarse en cualquier pin, pero no es tan eficiente. Estas clases tienen los mismos métodos disponibles y difieren principalmente en la forma en que se construyen.

Ejemplo de uso:

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.

Constructores

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)

Construye un objeto SPI en el bus indicado, id. Los valores de id dependen de un puerto concreto y su hardware. Los valores 0, 1, etc. se usan habitualmente para seleccionar el bloque SPI de hardware n.º 0, n.º 1, etc.

Sin parámetros adicionales, el objeto SPI se crea pero no se inicializa (tiene la configuración de la última inicialización del bus, si la hubo). Si se proporcionan argumentos adicionales, el bus se inicializa. Consulte init para conocer los parámetros de inicialización.

Métodos

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

Inicializa el bus SPI con los parámetros indicados:

  • baudrate es la velocidad de reloj de SCK.

  • polarity puede ser 0 o 1, y es el nivel en el que reposa la línea de reloj en estado inactivo.

  • phase puede ser 0 o 1 para muestrear los datos en el primer o el segundo flanco de reloj, respectivamente.

  • bits es el ancho en bits de cada transferencia. Solo se garantiza que todo el hardware admita 8.

  • firstbit puede ser SPI.MSB o SPI.LSB.

  • sck, mosi, miso son objetos pin (machine.Pin) que se usarán para las señales del bus. Para la mayoría de los bloques SPI de hardware (seleccionados mediante el parámetro id del constructor), los pines son fijos y no pueden cambiarse. En algunos casos, los bloques de hardware permiten 2-3 conjuntos alternativos de pines para un bloque SPI de hardware. Las asignaciones arbitrarias de pines solo son posibles para un controlador SPI por bit-banging (id = -1).

En el caso del SPI por hardware, la frecuencia de reloj real puede ser inferior a la velocidad en baudios solicitada. Esto depende del hardware de la plataforma. La velocidad real puede determinarse imprimiendo el objeto SPI.

deinit() None

Apaga el bus SPI.

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

Lee un número de bytes especificado por nbytes mientras escribe continuamente el único byte indicado por write. Devuelve un objeto bytes con los datos leídos.

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

Lee en el búfer especificado por buf mientras escribe continuamente el único byte indicado por write. Devuelve None.

write(buf: bytes) None

Escribe los bytes contenidos en buf. Devuelve None.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Escribe los bytes de write_buf mientras lee en read_buf. Los búferes pueden ser el mismo o distintos, pero ambos deben tener la misma longitud. Devuelve None.

Constantes

MSB: int

Pase a firstbit para transmitir/recibir primero el bit más significativo (el orden más común).

LSB: int

Pase a firstbit para transmitir/recibir primero el bit menos significativo.

class SoftSPI – bus SPI emulado por software

La clase SoftSPI implementa SPI mediante bit-banging de pines GPIO arbitrarios. Expone la misma superficie de métodos que SPI, por lo que el código existente que apunta al SPI por hardware puede cambiar a software solo con un cambio en el constructor. Úsela cuando los pines que necesita no estén cableados a un bloque SPI de hardware, cuando necesite más buses de los disponibles por hardware, o cuando un periférico requiera una fase de reloj no estándar que el hardware no pueda producir.

Constructores

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)

Construye un objeto SPI por software. sck, mosi y miso deben proporcionarse: no hay selección de pines implícita. Consulte SPI.init() para conocer el significado de los demás parámetros. El baudrate predeterminado es inferior al del SPI por hardware porque el bucle de bit-banging tiene más sobrecarga.

Métodos

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

Reinicializa el bus SPI por software con los parámetros indicados. Solo se actualizan los argumentos proporcionados; los demás conservan sus valores anteriores. Consulte SPI.init() para conocer el significado de cada argumento.

deinit() None

Libera los pines GPIO reclamados por el controlador de bit-banging y deja de gobernar el bus.

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

Lee nbytes bytes mientras escribe continuamente el único byte write. Devuelve un objeto bytes que contiene los datos recibidos.

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

Lee en buf mientras escribe continuamente el único byte write. Devuelve None.

write(buf: bytes) None

Escribe buf en el bus. Los bytes recibidos se descartan.

write_readinto(write_buf: bytes, read_buf: bytearray) None

Escribe write_buf y lee en read_buf simultáneamente. Ambos búferes deben tener la misma longitud; pueden solaparse.

Constantes

MSB: int

Pase a firstbit para transmitir/recibir primero el bit más significativo.

LSB: int

Pase a firstbit para transmitir/recibir primero el bit menos significativo.