class SPI -- 由控制器驱动的串行协议

SPI 是一种由控制器驱动的同步串行协议。在物理层面,它使用三条线(SCKMOSIMISO)外加每个外设一条的片选线。

其用法类似于 I2C;主要区别在于初始化总线时传入的参数:

from pyb import SPI
spi = SPI(2, SPI.CONTROLLER, baudrate=600000, polarity=1, phase=0, crc=0x7)

唯一必需的参数是 modeSPI.CONTROLLERSPI.PERIPHERAL)。polaritySCK 的空闲电平(01)。phase 用于选择数据是在第一个(0)还是第二个(1)时钟边沿采样。crc 可以是 None(无 CRC)或一个 CRC 多项式。

传输数据:

data = spi.send_recv(b"1234")        # send 4 bytes and receive 4 bytes
buf = bytearray(4)
spi.send_recv(b"1234", buf)          # send 4 bytes and receive 4 into buf
spi.send_recv(buf, buf)              # send/receive 4 bytes through buf

构造函数

class pyb.SPI(bus: int | str, *args, **kwargs)

在给定的 bus(一个整数 SPI 外设索引,例如 2 对应 SPI2)上构造一个 SPI 对象。不带额外参数时,对象会被创建但不被初始化(它会保留之前的总线设置(如果有的话));如果给定了额外的参数,则使用它们初始化总线。可用参数请参阅 init()

SPI(2) 在每块 STM32 OpenMV Cam 上都连接到相同的排针引脚;OpenMV Cam N6 还额外提供 SPI(4)

总线

NSS

SCK

MISO

MOSI

SPI(2)(所有 STM32 OpenMV Cam)

P3

P2

P1

P0

SPI(4)(仅限 OpenMV Cam N6)

P15

P16

P17

P18

在两条总线上,NSS 都不由 SPI 外设驱动;它可以自由地用作普通的 GPIO 片选。

方法

deinit() None

关闭 SPI 总线。

init(mode: int, baudrate: int = 328125, *, prescaler: int = -1, polarity: int = 1, phase: int = 0, bits: int = 8, firstbit: int = SPI.MSB, ti: bool = False, crc: int | None = None) None

使用给定参数初始化 SPI 总线:

  • mode 必须是 SPI.CONTROLLERSPI.PERIPHERAL

  • baudrate 是 SCK 时钟速率(仅对控制器有意义)。

  • prescaler 是用于从 APB 总线频率推导出 SCK 的预分频器;使用 prescaler 会覆盖 baudrate

  • polarity 可以是 0 或 1,是空闲时钟线所处的电平。

  • phase 可以是 0 或 1,分别表示在第一个或第二个时钟边沿采样数据。

  • bits 可以是 8 或 16,是每个传输字的位数。

  • firstbit 可以是 SPI.MSBSPI.LSB

  • ti 为 True 表示采用 Texas Instruments 而非 Motorola 的信号约定。

  • crc 可以为 None 表示无 CRC,或为一个多项式说明符。

SPI 时钟频率可能不会精确匹配 baudrate。硬件仅支持父级 APB 总线频率除以一个 2 的幂预分频器(2, 4, 8, 16, 32, 64, 128256)得到的时钟;驱动会选择不超过所请求 baudrate 的最高时钟。SPI(2) 位于 APB1 上。若要精确控制时钟,请直接设置 prescaler 而不是 baudrate

打印 SPI 对象会显示计算得到的波特率和所选的预分频器。

recv(recv: int | bytearray, *, timeout: int = 5000) bytes

在总线上接收数据:

  • recv 可以是一个整数,表示要接收的字节数;也可以是一个可变缓冲区,将被接收到的字节填充。

  • timeout 是等待接收的超时时间,单位为毫秒。

返回值:如果 recv 是整数,则返回包含所接收字节的新缓冲区,否则返回传入 recv 的同一缓冲区。

send(send: int | bytes | bytearray, *, timeout: int = 5000) None

在总线上发送数据:

  • send 是要发送的数据(一个要发送的整数,或一个缓冲区对象)。

  • timeout 是等待发送的超时时间,单位为毫秒。

send_recv(send: int | bytes | bytearray, recv: bytearray | None = None, *, timeout: int = 5000) bytes

在总线上同时发送和接收数据:

  • send 是要发送的数据(一个要发送的整数,或一个缓冲区对象)。

  • recv 是一个可变缓冲区,将被接收到的字节填充。它可以与 send 相同,也可以省略。如果省略,则会创建一个新的缓冲区。

  • timeout 是等待接收的超时时间,单位为毫秒。

返回值:包含所接收字节的缓冲区。

常量

CONTROLLER: int

将 SPI 总线初始化为主机(控制器)—— OpenMV Cam 驱动 SCKMOSI 并负责整个事务。

PERIPHERAL: int

将 SPI 总线初始化为从机(外设)—— OpenMV Cam 响应由远端控制器驱动的时钟脉冲。

MSB: int

传给 firstbit 以最高有效位优先传输/接收(最常见的顺序)。

LSB: int

传给 firstbit 以最低有效位优先传输/接收。