跳转至

i2c - I2C操作

以下为关键点梳理

一、模块概述

I2C 模块用于实现与 I2C 设备的通信,提供了硬件 I2C 和软件模拟 I2C 的功能,支持数据发送、接收、寄存器操作以及设备扫描等操作,适用于多种 I2C 设备的连接与控制。

二、Air780EPM 软硬件对照表

  • Air780EPM PIN66:I2C1_SDA;PIN67:I2C1_SCL;
  • LuatOS 中对应的 I2C ID 是 1 ;

三、核心功能与用法

(一)I2C 设备检测与初始化

  • i2c.exist(id) :检测指定编号的 I2C 设备是否存在。

    • 参数id 为 I2C 设备编号。
    • 返回值 :存在返回 true,不存在返回 false
    • 示例if i2c.exist(1) then log.info("存在 i2c1") end :检查 i2c1 是否存在。
    • i2c.setup(id, speed, pullup) :初始化 I2C 设备。

    • 参数id 为设备编号;speed 设置通信速率,如 i2c.FASTpullup 配置上拉电阻。

    • 返回值 :无。
    • 示例i2c.setup(1, i2c.FAST) :初始化 i2c1,设置为快速模式。
    • i2c.createSoft(scl, sda, delay) :创建软件模拟 I2C 对象。

    • 参数sclsda 分别为时钟线和数据线的 GPIO 编号;delay 调整 I2C 速度。

    • 返回值 :返回软件 I2C 对象。
    • 示例local softI2C = i2c.createSoft(1, 2, 5) :创建软件 I2C,使用 GPIO1 和 GPIO2,设置延迟为 5。

(二)I2C 数据传输

  • i2c.send(id, addr, data, stop) :向 I2C 设备发送数据。

    • 参数id 为 I2C 设备编号;addr 为目标设备地址;data 为要发送的数据;stop 控制是否发送停止信号。
    • 返回值 :如果从机有响应, 返回true, 否则返回false。
    • 示例i2c.send(0, 0x68, 0x75) :往 i2c0 的地址为 0x68 的设备发送一个字节数据 0x75。
    • i2c.recv(id, addr, len) :从 I2C 设备接收数据。

    • 参数idaddr 同上;len 为要接收的数据长度。

    • 返回值 :返回接收到的数据。
    • 示例local data = i2c.recv(1, 0x5C, 2) :从 i2c1 的地址为 0x5C 的设备读取 2 个字节数据。

(三)I2C 通用传输与非阻塞传输

  • i2c.transfer(id, addr, txBuff, rxBuff, rxLen) :I2C 通用传输,可实现发送、发送后接收、仅接收等功能。

    • 参数idaddr 同上;txBuff 为要发送的数据缓冲区;rxBuff 为接收数据的缓冲区;rxLen 为要接收的数据长度。
    • 返回值 :返回传输结果。
    • 示例local result, _ = i2c.transfer(0, 0x11, txbuff, rxbuff, 1) :发送数据并接收 1 个字节。
    • i2c.xfer(id, addr, txBuff, rxBuff, rxLen, transfer_done_topic, timeout) :I2C 非阻塞通用传输,调用后立即返回,传输完成后通过消息回调。

    • 参数 :同上,新增 transfer_done_topic 为传输完成后的消息回调主题;timeout 为超时时间。

    • 返回值 :返回传输是否成功发起。
    • 示例local result = i2c.xfer(0, 0x11, txbuff, rxbuff, 1, "I2CDONE") :发起非阻塞传输,完成后通过 "I2CDONE" 主题回调。

(四)I2C 设备扫描

  • i2c.scan(id, speed) :扫描 I2C 总线上的设备。
    • 参数id 为 I2C 设备编号;speed 设置扫描时的通信速率。
    • 返回值 :返回扫描到的设备地址列表。
    • 示例i2c.scan() :扫描 I2C 设备。

(五)特殊功能

  • i2c.readDHT12(id) :从 I2C 总线读取 DHT12 的温湿度数据。

    • 参数id 为 I2C 设备编号。
    • 返回值 :返回读取结果、湿度和温度。
    • 示例local re, H, T = i2c.readDHT12(0) :从 i2c0 读取 DHT12 数据。
    • i2c.readSHT30(id, addr) :从 I2C 总线读取 SHT30 的温湿度数据。

    • 参数id 为 I2C 设备编号;addr 为目标设备地址。

    • 返回值 :返回读取结果、湿度和温度。
    • 示例local re, H, T = i2c.readSHT30(0) :从 i2c0 读取 SHT30 数据。

四、其他信息

  1. 函数依赖与限制 :在使用 i2c.sendi2c.recv 等函数时,需确保对应的 I2C 设备已通过 i2c.setup 正确初始化。对于软件 I2C,不需要调用 i2c.close 接口。
  2. 数据格式 :在发送和接收数据时,数据格式需符合 I2C 设备的通信协议要求,如寄存器地址、数据字节顺序等。
  3. 版本更新 :文档中部分函数如 i2c.transferi2c.xferi2c.scan 等有明确的版本更新记录,使用时需注意版本兼容性。

以下为详细说明

常量

常量 类型 解释
i2c.FAST number 高速
i2c.SLOW number 低速

i2c.exist(id)

i2c编号是否存在

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2

返回值

返回值类型 解释
bool 存在就返回true,否则返回false

例子

-- 检查i2c1是否存在
if i2c.exist(1) then
    log.info("存在 i2c1")
end

i2c.setup(id, speed, pullup)

i2c初始化

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int I2C速度, 例如i2c.FAST
bool 是否软件上拉, 默认不开启,需要硬件支持

返回值

返回值类型 解释
int 成功就返回1,否则返回0

例子

-- 初始化i2c1
i2c.setup(1, i2c.FAST) -- id正确就一定成功
-- 如需判断i2c id是否合法, 请使用 i2c.exist 函数

i2c.createSoft(scl,sda,delay)

新建一个软件i2c对象

参数

传入值类型 解释
int i2c SCL引脚编号(GPIO编号)
int i2c SDA引脚编号(GPIO编号)
int 每个操作的延时, 单位us, 默认5

返回值

返回值类型 解释
软件I2C对象 可当作i2c的id使用

例子

-- 注意!这个接口是软件模拟i2c,速度可能会比硬件的慢
-- 不需要调用i2c.close接口
-- 初始化软件i2c
local softI2C = i2c.createSoft(1, 2, 5)
i2c.send(softI2C, 0x5C, string.char(0x0F, 0x2F))
-- 注意, 第3个参数是 2023.06.19 添加的delay
-- 通过调整delay参数的值, 可增加或降低I2C的速度

i2c.send(id, addr, data,stop)

i2c发送数据

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int I2C子设备的地址, 7位地址
integer/string/table 待发送的数据,自适应参数类型
integer 可选参数 是否发送停止位 1发送 0不发送 默认发送

返回值

返回值类型 解释
true/false 如果从机有响应, 返回true, 否则返回false

例子

-- 往i2c0发送1个字节的数据
i2c.send(0, 0x68, 0x75)
-- 往i2c1发送2个字节的数据
i2c.send(1, 0x5C, string.char(0x0F, 0x2F))
i2c.send(1, 0x5C, {0x0F, 0x2F})

i2c.recv(id, addr, len)

i2c接收数据

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int I2C子设备的地址, 7位地址
int 接收数据的长度

返回值

返回值类型 解释
string 收到的数据

例子

-- 从i2c1读取2个字节的数据
local data = i2c.recv(1, 0x5C, 2)

i2c.close(id)

关闭i2c设备

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2

返回值

返回值类型 解释
nil 无返回值

例子

-- 关闭i2c1
i2c.close(1)

i2c.readDHT12(id)

从i2c总线读取DHT12的温湿度数据

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int DHT12的设备地址,默认0x5C

返回值

返回值类型 解释
boolean 读取成功返回true,否则返回false
int 湿度值,单位0.1%, 例如 591 代表 59.1%
int 温度值,单位0.1摄氏度, 例如 292 代表 29.2摄氏度

例子

-- 从i2c0读取DHT12
i2c.setup(0)
local re, H, T = i2c.readDHT12(0)
if re then
    log.info("dht12", H, T)
end

i2c.readSHT30(id,addr)

从i2c总线读取DHT30的温湿度数据(由"好奇星"贡献)

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int 设备addr,SHT30的设备地址,默认0x44 bit7

返回值

返回值类型 解释
boolean 读取成功返回true,否则返回false
int 湿度值,单位0.1%, 例如 591 代表 59.1%
int 温度值,单位0.1摄氏度, 例如 292 代表 29.2摄氏度

例子

-- 从i2c0读取SHT30
i2c.setup(0)
local re, H, T = i2c.readSHT30(0)
if re then
    log.info("sht30", H, T)
end

i2c.transfer(id, addr, txBuff, rxBuff, rxLen)

i2c通用传输,包括发送N字节,发送N字节+接收N字节,接收N字节三种功能,在发送转接收过程中发送reStart信号,解决类似mlx90614必须带restart信号,但是又不能用i2c.send来控制的,比如air105

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int I2C子设备的地址, 7位地址
integer/string/zbuff 待发送的数据,自适应参数类型,如果为nil,则不发送数据
zbuff 待接收数据的zbuff 如果不用zbuff,则接收数据将在return返回
int 需要接收的数据长度,如果为0或nil,则不接收数据

返回值

返回值类型 解释
boolean true/false 发送是否成功
string or nil 如果参数5是interger,则返回接收到的数据

例子

local result, _ = i2c.transfer(0, 0x11, txbuff, rxbuff, 1)
local result, _ = i2c.transfer(0, 0x11, txbuff, nil, 0)    --只发送txbuff里的数据,不接收数据,典型应用就是写寄存器了,这里寄存器地址和值都放在了txbuff里
local result, _ = i2c.transfer(0, 0x11, "\x01\x02\x03", nil, 1) --发送0x01, 0x02,0x03,不接收数据,如果是eeprom,就是往0x01的地址写02和03,或者往0x0102的地址写03,看具体芯片了
local result, rxdata = i2c.transfer(0, 0x11, "\x01\x02", nil, 1) --发送0x01, 0x02,然后接收1个字节,典型应用就是eeprom
local result, rxdata = i2c.transfer(0, 0x11, 0x00, nil, 1) --发送0x00,然后接收1个字节,典型应用各种传感器

i2c.xfer(id, addr, txBuff, rxBuff, rxLen, transfer_done_topic, timeout)

i2c非阻塞通用传输,类似transfer,但是不会等到I2C传输完成才返回,调用本函数会立刻返回,I2C传输完成后,通过消息回调

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int I2C子设备的地址, 7位地址
zbuff 待发送的数据,由于用的非阻塞模型,为保证动态数据的有效性,只能使用zbuff,发送的数据从zbuff.addr开始,长度为zbuff.used
zbuff 待接收数据的zbuff,如果为nil,则忽略后面参数, 不接收数据。接收的数据会放在zbuff.addr开始的位置,会覆盖掉之前的数据,注意zhuff的预留空间要足够
int 需要接收的数据长度,如果为0或nil,则不接收数据
string 传输完成后回调的消息
int 超时时间,如果填nil,则为100ms

返回值

返回值类型 解释
boolean true/false 本次传输是否正确启动,true,启动,false,有错误无法启动。传输完成会发布消息transfer_done_topic和boolean型结果

例子

local result = i2c.xfer(0, 0x11, txbuff, rxbuff, 1, "I2CDONE") if result then result, i2c_id, succ, error_code = sys.waitUntil("I2CDONE") end if not result or not succ then log.info("i2c fail, error code", error_code) else log.info("i2c ok") end

i2c.scan(id,speed)

扫描i2c设备

参数

传入值类型 解释
int 设备id, 例如i2c1的id为1, i2c2的id为2
int 速度, 可选i2c.SLOW i2c.FAST i2c.PLUS i2c.HSMODE 默认为i2c.SLOW,如探测不到则修改此项

返回值

返回值类型 解释
nil 当前无返回值

例子

-- 本函数于2023.07.04添加
-- 这个函数的主要目标是为了在开发期扫描i2c设备
-- 有些BSP在指定addr无响应时会输出日志,导致输出会被打乱
i2c.scan()