I2C 类 – 一种两线串行协议

I2C 是一种用于设备间通信的两线协议。在物理层,它由 2 条线组成:SCL 和 SDA,分别是时钟线和数据线。

I2C 对象是附加到特定总线上创建的。它们可以在创建时初始化,也可以稍后初始化。

打印 I2C 对象可为您提供有关其配置的信息。

硬件和软件 I2C 实现都通过 machine.I2Cmachine.SoftI2C类存在 。硬件 I2C 使用系统的底层硬件支持来执行读/写,并且通常高效且快速,但可能对可以使用的引脚有限制。软件 I2C 是通过位组合实现的,可以在任何引脚上使用,但效率不高。这些类具有相同的可用方法,主要区别在于它们的构造方式。

用法示例:

from machine import I2C

i2c = I2C(freq=400000)          # create I2C peripheral at frequency of 400kHz
                                # depending on the port, extra parameters may be required
                                # to select the peripheral and/or pins to use

i2c.scan()                      # scan for slaves, returning a list of 7-bit addresses

i2c.writeto(42, b'123')         # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(42, 4)             # read 4 bytes from slave with 7-bit address 42

i2c.readfrom_mem(42, 8, 3)      # read 3 bytes from memory of slave 42,
                                #   starting at memory-address 8 in the slave
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
                                #   starting at address 2 in the slave

构造函数

class machine.I2C(id, *, scl, sda, freq=400000)

使用以下参数构造并返回一个新的 I2C 对象:

  • id标识特定的 I2C 外设。允许的值取决于特定的端口/板

  • scl应该是一个 pin 对象,指定用于 SCL 的 pin。

  • sda应该是一个 pin 对象,指定用于 SDA 的 pin。

  • freq应该是一个整数,用于设置 SCL 的最大频率。

请注意,某些端口/板将具有 可以在此构造函数中更改的scl和sda 的默认值。其他人将具有无法更改的固定值scl和sda。

class machine.SoftI2C(scl, sda, *, freq=400000, timeout=255)

构造一个新的软件 I2C 对象。参数是:

  • scl应该是一个 pin 对象,指定用于 SCL 的 pin。

  • sda应该是一个 pin 对象,指定用于 SDA 的 pin。

  • freq应该是一个整数,用于设置 SCL 的最大频率。

  • timeout是等待时钟延长(SCL 被总线上的另一个设备保持为低电平)的最长时间(以微秒为单位),之后会引发OSError(ETIMEDOUT) 异常。

一般方法

I2C.init(scl, sda, *, freq=400000)

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

  • scl是 SCL 线的引脚对象

  • sda是 SDA 线的引脚对象

  • freq是 SCL 时钟频率

I2C.deinit()

关闭 I2C 总线。

可用性:WiPy。

I2C.scan()

扫描 0x08 和 0x77 之间的所有 I2C 地址,并返回响应的列表。如果在总线上发送其地址(包括写位)后将 SDA 线拉低,则设备会做出响应。

原始 I2C 操作

以下方法实现了原始 I2C 主控总线操作,可以组合起来进行任何 I2C 事务。如果您需要对总线进行更多控制,则会提供它们,否则可以使用标准方法(见下文)。

这些方法仅在machine.SoftI2C类上可用。

I2C.start()

在总线上产生一个 START 条件(SCL 为高时 SDA 转换为低)。

I2C.stop()

在总线上产生一个 STOP 条件(SCL 为高时 SDA 转换为高)。

I2C.readinto(buf, nack=True, /)

从总线读取字节并将它们存储到buf 中。读取的字节数是buf的长度。收到除最后一个字节以外的所有字节后,将在总线上发送 ACK。接收到最后一个字节后,如果nack 为真,则将发送 NACK,否则将发送 ACK(在这种情况下,从设备假定将在以后的调用中读取更多字节)。

I2C.write(buf)

将字节从buf写入总线。检查每个字节后是否收到 ACK,如果收到 NACK,则停止传输剩余的字节。该函数返回接收到的 ACK 数。

标准总线操作

以下方法实现了针对给定从设备的标准 I2C 主设备读写操作。

I2C.readfrom(addr, nbytes, stop=True, /)

从addr指定的从站读取nbytes。如果stop为真,则在传输结束时生成 STOP 条件。返回读取数据的对象。bytes object with the data read.

I2C.readfrom_into(addr, buf, stop=True, /)

从addr指定的从站读入buf。读取的字节数将是buf的长度。如果stop为真,则在传输结束时生成 STOP 条件。

该方法返回None

I2C.writeto(addr, buf, stop=True, /)

将buf 中的字节写入addr指定的从站。如果在从buf写入一个字节后收到 NACK,则不会发送剩余的字节。如果stop为真,则在传输结束时生成 STOP 条件,即使收到 NACK 也是如此。该函数返回接收到的 ACK 数。

I2C.writevto(addr, vector, stop=True, /)

将vector 中包含的字节写入addr指定的从站。 vector应该是具有缓冲协议的元组或对象列表。该地址一次,然后从每个对象中的字节被发送矢量 被顺序地写出。vector 中的对象的长度可能为零字节,在这种情况下,它们对输出没有贡献。

如果在从vector中的对象之一写入字节后收到 NACK ,则不会发送剩余的字节和任何剩余的对象。如果stop为真,则在传输结束时生成 STOP 条件,即使收到 NACK 也是如此。该函数返回接收到的 ACK 数。

内存操作

一些 I2C 设备充当可以读取和写入的存储设备(或一组寄存器)。在这种情况下,有两个地址与 I2C 事务相关联:从地址和存储器地址。以下方法是与此类设备通信的便利功能。

I2C.readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)

从memaddr指定的内存地址开始,从addr指定的从站读取nbytes。参数addrsize以位为单位指定地址大小。返回读取数据的对象。bytes.

I2C.readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)

从memaddr指定的内存地址开始,从addr指定的从站读入buf。读取的字节数是buf的长度。参数addrsize以位为单位指定地址大小(在 ESP8266 上无法识别此参数,地址大小始终为 8 位)。

该方法返回None.

I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)

从memaddr指定的内存地址开始,将buf写入addr指定的从站。参数addrsize以位为单位指定地址大小(在 ESP8266 上无法识别此参数,地址大小始终为 8 位)。

该方法返回 None.