class I2C —— 一种两线串行协议

I2C 是一种用于设备间通信的两线协议。在物理层面上,它由两条线组成:SCL(时钟)和 SDA(数据)。OpenMV Cam 在任何一条线上提供板载上拉电阻 —— 总线要正常工作,SCLSDA 上都需要外部上拉电阻。

I2C 对象关联到特定的总线,可以在构造时初始化,也可以稍后通过 init() 初始化。

示例::

from pyb import I2C

i2c = I2C(2)                              # create on bus 2 (uninitialised)
i2c = I2C(2, I2C.CONTROLLER)              # create and init as a controller
i2c.init(I2C.CONTROLLER, baudrate=20000)  # init as a controller
i2c.init(I2C.PERIPHERAL, addr=0x42)       # init as a peripheral with the given address
i2c.deinit()                              # turn off the peripheral

打印 I2C 对象会显示其配置。

基本方法是 send()recv()::

i2c.send("abc")      # send 3 bytes
i2c.send(0x42)       # send a single byte, given by the number
data = i2c.recv(3)   # receive 3 bytes

要就地接收,先创建一个 bytearray::

data = bytearray(3)  # create a buffer
i2c.recv(data)       # receive 3 bytes, writing them into data

你可以指定超时时间(以毫秒为单位)::

i2c.send(b"123", timeout=2000)   # timeout after 2 seconds

控制器必须指定接收方的地址::

i2c.init(I2C.CONTROLLER)
i2c.send("123", 0x42)        # send 3 bytes to peripheral with address 0x42
i2c.send(b"456", addr=0x42)  # keyword for address

控制器还具有以下方法::

# Check if peripheral 0x42 is ready.
i2c.is_ready(0x42)

# Scan the bus and return a list of responding addresses.
i2c.scan()

# Read 3 bytes from peripheral 0x42 starting at memaddr 2.
i2c.mem_read(3, 0x42, 2)

# Write 3 bytes to peripheral 0x42 at memaddr 2.
i2c.mem_write("abc", 0x42, 2, timeout=1000)

构造函数

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

在给定的 bus(一个整数外设索引,例如 2 对应 I2C2)上构造一个 I2C 对象。如果没有额外参数,则创建对象但不初始化(它会保留先前的总线设置,如果有的话);如果给定了额外参数,则初始化总线。可用参数见 init()

在每一款暴露 pyb.I2C 的 OpenMV Cam(M4 / M7 / H7 / H7 Plus / Pure Thermal)上,I2C(2) 都接线到相同的排针引脚:

信号

排针引脚

备注

SCL

P4

SDA

P5

I2C(4) 在 OpenMV Cam M7、H7、H7 Plus 和 Pure Thermal 上额外可用,SCL 位于排针引脚 P7SDA 位于排针引脚 P8

OpenMV Cam N6 不暴露 pyb.I2C;请改用 machine.I2C

方法

deinit() None

关闭 I2C 总线。

init(mode: int, *, addr: int = 0x12, baudrate: int = 400000, gencall: bool = False, dma: bool = False) None

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

  • mode 必须是 I2C.CONTROLLERI2C.PERIPHERAL

  • addr 是 7 位地址(仅对外设有意义)。

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

  • gencall 表示是否支持广播呼叫(general-call)模式。

  • dma 表示是否允许对 I2C 传输使用 DMA(注意,DMA 传输的时序更精确,但目前无法正确处理总线错误)。

实际时钟频率可能低于请求的频率。这取决于平台硬件。实际速率可通过打印 I2C 对象来确定。

is_ready(addr: int) bool

检查某个 I2C 设备是否对给定地址作出响应。仅在控制器模式下有效。

mem_read(data: int | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) bytes

从 I2C 设备的内存读取:

  • data 可以是一个整数(要读取的字节数)或一个用于读入的缓冲区

  • addr 是 I2C 设备地址

  • memaddr 是 I2C 设备内的内存位置

  • timeout 是等待读取的超时时间(以毫秒为单位)

  • addr_size 选择 memaddr 的宽度:8 位或 16 位

返回读取的数据。仅在控制器模式下有效。

mem_write(data: int | bytes | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) None

写入 I2C 设备的内存:

  • data 可以是一个整数或一个用于写入的缓冲区。

  • addr 是 I2C 设备地址。

  • memaddr 是 I2C 设备内的内存位置。

  • timeout 是等待写入的超时时间(以毫秒为单位)。

  • addr_size 选择 memaddr 的宽度:8 位或 16 位。

仅在控制器模式下有效。

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

在总线上接收数据:

  • recv 可以是一个整数,即要接收的字节数;也可以是一个可变缓冲区,它将被填入接收到的字节

  • addr 是要从中接收数据的地址(仅在控制器模式下需要)

  • timeout 是等待接收的超时时间(以毫秒为单位)

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

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

在总线上发送数据:

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

  • addr 是要发送到的地址(仅在控制器模式下需要)。

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

scan() List[int]

扫描从 0x01 到 0x7f 的所有 I2C 地址,并返回作出响应的地址列表。仅在控制器模式下有效。

常量

CONTROLLER: int

将总线初始化为主设备(控制器)—— 它驱动 SCL 并发起事务。

PERIPHERAL: int

将总线初始化为从设备(外设),它监听在 init() 中设置的 addr,并响应同一总线上由控制器发起的事务。