注意

这是最新开发分支配套的文档,可能包含已发布版本中尚未提供的功能。如果您要查看特定版本的文档,请使用左侧的下拉菜单并选择所需要的版本。

I2C 使用教程(主机模式)#

概述#

I2C(Inter-Integrated Circuit)是一种二线式通信协议,通过 SDA 和 SCL 两条线路进行数据传输。

K230 芯片内部集成5个硬件 I2C 控制器,支持下列通信模式:

  • 标准模式(Standard,100kbps)

  • 快速模式(Fast,400kbps)

  • 高速模式(High Speed,3.4Mbps)

通过 FPIOA 模块,可将 I2C 接口选择分配到指定 IO 线路,应用类型包括 EEPROM 、IMU 传感器、OLED 显示器等外设。

注意:

  1. 在进行如下I2C操作之前,需要确保已将相应的引脚切换为 I2C 功能。请参考 FPIOA使用指南了解如何切换芯片引脚功能。

  2. I2C 总线需要在 SDA/SCL 上接上拉阻值,通常为 4.7kΩ。

  3. 与官方 API 相比,K230 所有 I2C API 函数不支持 stop=False 参数, 即每个上层 API 调用后均会发送一个 I2C STOP 信号,相当于 stop=True

  4. 不提供 start(), stop(), readinto(), write() 4个底层 I2C API 的直接调用。

I2C 使用示例#

常规 I2C 操作 API#

方法

作用

init()

重新初始化 I2C 控制器

scan()

扫描总线上响应设备

初始化 I2C 设备#

from machine import I2C
i2c = I2C(2, scl=11, sda=12, freq=40000)  # 默认为 100kHz

扫描 I2C 总线设备列表#

通过调用 scan() 方法,我们可以扫描出当前 I2C 总线上挂载的所有设备的地址。

print(i2c.scan())  # 返回第一个响应的设备地址,如 [59]

输出如下:可以看出,在 I2C2 总线上我们扫描出来一个设备,它的地址是 80,实际是一颗 24C32 EEPROM。

[80]

标准 I2C 总线操作#

I2C 总线操作直接和 I2C 从设备交互,不涉及从设备的“内部寄存器”或“内存地址”。

I2C 总线操作方法列表如下:

方法

读/写

特点

readfrom

返回一个新的 bytes

readfrom_into

把数据写入现有 buf

writeto

一次写入一个 bytes/bytearray

writevto

一次写入多个 buffer

readfrom(addr, nbytes, stop=True)#

功能: 直接从设备读取 nbytes 字节数据。 返回值: bytes 对象。

例:

data = i2c.readfrom(0x50, 4)  # 从设备地址 0x50 读 4 个字节

readfrom_into(addr, buf, stop=True)#

功能:readfrom 类似,但把数据写入已有的 bytearray 缓冲区中。 返回值: 无(直接填充 buf

例:

buf = bytearray(4)
i2c.readfrom_into(0x50, buf)

writeto(addr, buf, stop=True)#

功能: 向设备写入一个 buf 数据。 返回值: 接收到 ACK 的字节数。

例:

i2c.writeto(0x50, b'\x01\x02')

writevto(addr, vector, stop=True)#

功能:writeto 类似,但 vector 是多个 buffer 组成的列表或元组,会一次性连续发送多个数据段返回值: 接收到 ACK 的字节数。

适合: 需要先发命令再发数据的场景。

例:

i2c.writevto(0x50, (b'\x00', b'\x01\x02'))  # 先发0x00,再发0x01 0x02

存储类 I2C 操作#

很多 I2C 设备(如 EEPROM、RTC)内部有“寄存器地址”或“内存地址”。要先写地址再读写数据。

这些方法是 封装了 “写内存地址 + 读写数据” 的便捷函数。

方法

读/写

特点

readfrom_mem

读取 memaddr 起始地址的 n 个字节

readfrom_mem_into

同上,但写入现有 buf

writeto_mem

写入 memaddr 地址

readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)#

功能:memaddr 处读取 nbytes 字节。 内部相当于: write(memaddr)read(nbytes) 返回值: bytes

例:

data = i2c.readfrom_mem(0x50, 0x0000, 4, addrsize=16)

readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)#

功能: 同上,但把数据写入 buf 中。 返回值:

例:

buf = bytearray(4)
i2c.readfrom_mem_into(0x50, 0x0000, buf, addrsize=16)

writeto_mem(addr, memaddr, buf, *, addrsize=8)#

功能: 向设备的 memaddr 地址写入数据。 内部相当于: write(memaddr + buf) 返回值:

例:

i2c.writeto_mem(0x3b, 0xff, b'\x80', mem_size=8)  # 页地址 0xFF = 0x80

常见问题 FAQ#

Q1: i2c.scan() 没有返回设备?#

请确保:

  • SDA/SCL 线路连接正确

  • FPIOA 是否正确配置成 IIC 功能,并已启用上拉

  • 是否加了外部上拉阻值 (4.7kΩ)

  • 从设备是否正常供电

Q2: I2C 地址是 7 位还是 8 位?#

K230 采用 7 位地址模式,而某些设备手册或示例中使用的是 8 位地址(含读写位),例如 0x78。这容易造成混淆。如果你看到设备手册中是 8 位(包括 R/W 位),请取高 7 位作为地址:

模式

示例地址

说明

7 位地址

0x3C

实际设备地址,K230使用

8 位地址

0x78

通常用于传输(即 0x3C << 1

如果你发现地址对不上,请尝试将 8 位地址右移一位。

Q3:执行 i2c.scan() 时卡住不响应?#

通常是因为 SCL 或 SDA 缺失上拉电阻,导致通信失败。请确认:

  • 电路中是否添加了 4.7k ~ 10k 的上拉电阻

  • 所连接的 I2C 设备是否供电正常

延伸阅读#

评论列表
条评论
登录