跳转至

I2C

一、I2C 概述:

I2C(Inter-Integrated Circuit)是一种广泛应用于嵌入式系统的通信协议,尤其适用于主从架构下的短距离通信。它最早由飞利浦(现在的NXP)公司开发,主要用于在集成电路内部以及设备之间的低速通信。以下是I2C协议的一些关键特性和工作原理:

物理层

  • I2C使用两根线进行数据传输:SCL(时钟线)和SDA(数据线)。

  • 两根线通过上拉电阻接到高电平,这样通信可以使用“线与”(Wired-AND)方式,方便多主多从架构。

  • SCL和SDA线分别传输时钟和数据,因此I2C通信是同步的。

架构

  • I2C采用主从(Master-Slave)结构。每次通信时只有一个主设 备,但可以有多个从设备。

  • 主设备负责生成时钟信号和启动/停止信号。

  • 从设备根据地址识别是否是目标通信对象。

通信流程

  • 起始条件(Start Condition):主设备将SDA线从高拉到低,而SCL保持高电平,表示通信的开始。

  • 地址传输:主设备发送从设备地址(7位或10位),并在末尾加入一个读/写位(0表示写,1表示读)。

  • 应答(ACK):从设备接收到地址后,如果地址匹配,就会拉低SDA线应答。

  • 数据传输:在数据传输过程中,每发送一个字节(8位)后,从设备都需要发送应答位。

  • 停止条件(Stop Condition):主设备将SDA线从低拉到高,而SCL保持高电平,表示通信结束。

二、演示功能概述

本例程将使用 I2C 协议读取传感器数据并打印出来。

三、准备硬件环境

3.1 Air201 模组

本次使用的开发板为 Air201模组,如下图所示:

点击链接购买:合宙Air201模组淘宝购买链接

此模组的详细使用说明参考:Air201 产品手册

3.2 BTB扩展板

由于Air201设计的很小巧,没有将所有的引脚测试点都预留到Air201的板子上,我们可以通过BTB连接器将一些引脚扩展出来,这里搭配使用了BTB扩展板。

3.3 数据通信线

typec 接口 USB 数据线即可。

3.4 PC 电脑

WIN10以及以上版本的WINDOWS系统。

3.5 sht20 温湿度传感器一个

3.6 Air201 ,BTB扩展板与 sht20 接线图如下

四、准备软件环境

4.1 基本的下载调试工具

使用说明参考:Luatools 下载和详细使用

五、使用 I2C 读取 sht20 软硬件资料:

5.1 文档和工具:

5.2 I2C硬件参考资料

I2C 配置:

兼容 Philips I2C 标准协议。

支持 Fast mode (400Kbps)和 Slow mode(100Kbps)。

只支持 master 模式,不支持 slave 模式。

理论上最多可支持 127 个从设备。

5.3 sht20介绍

sht20特点:

  • 完全校准
  • 数字输出,I2C接口
  • 低功耗
  • 优异的长期稳定性
  • DFN型封装 - 可回流焊接
  • 工作电压范围是2.1~3.6V.
  • I2C速率支持400k
  • 读取温度的命令为:0xF3
  • 读取湿度的命令为:0xF5

六、代码示例介绍

6.1 读取 SHT20 温湿度传感器

6.1.1 SHT20 简介:

SHT20 是使用 I2C 协议进行通信的温湿度传感器。

首先我们可以发送 STH20 的 7 位从机地址 +1 位读写位(写 0 读 1),然后发送 8 位的命令,0xF3 是读取温度的命令,0xF5 是读取湿度的命令。发送完后接收应答,等待 20us 之后我们发出 I2C 的结束时序。

6.1.2 demo 介绍

首先初始化 i2c

-- 按实际修改哦
    local id = 0

    --[[
        i2c初始化
        @param1    设备id, 例如i2c1的id为1, i2c2的id为2
        @param2    I2C速度, 例如i2c.FAST
        @param3    是否软件上拉, 默认不开启,需要硬件支持
        @return    成功就返回1,否则返回0
    ]]
    local ret = i2c.setup(id)
    log.info("i2c", "initial",ret)

然后给sht20发送读取温湿度命令,接收sht20回传的数据并打印即可。

        --第一种方式
        --[[
            i2c发送读取温度的命令
            @param1    设备id, 例如i2c1的id为1, i2c2的id为2
            @param2    I2C子设备的地址, 7位地址
            @param3    待发送的数据,自适应参数类型
            @param4    可选参数 是否发送停止位 1发送 0不发送 默认发送(105不支持)
            @return    发送是否成功
        ]]
        i2c.send(id, addr, string.char(0xF3))
        sys.wait(100)
        --[[
            i2c接收温度数据
            @param1    设备id, 例如i2c1的id为1, i2c2的id为2
            @param2    I2C子设备的地址, 7位地址
            @param3    接收数据的长度
            @return    收到的数据
        ]]
        tmp = i2c.recv(id, addr, 2)
        log.info("SHT20", "read tem data", tmp:toHex())

        --[[ 发送读取湿度的命令 ]]
        i2c.send(id, addr, string.char(0xF5))
        sys.wait(100)
        --[[ 接收湿度的数据 ]]
        hum = i2c.recv(id, addr, 2)
        log.info("SHT20", "read hum data", hum:toHex())

        local _,tval = pack.unpack(tmp,'>H')
        local _,hval = pack.unpack(hum,'>H')
        if tval and hval then
            --[[ 将温湿度数据转化成常规数据 ]]
            temp = (((17572 * tval) >> 16) - 4685)/100
            hump = (((12500 * hval) >> 16) - 600)/100
            log.info("SHT20", "temp,humi",temp,hump)
        end

七、功能验证:

成功使用 I2C 协议读取到 sht20 传感器的温湿度数值。

八、总结

本例程使用 i2c 协议读取了 sht20 传感器传输的温湿度数值。

扩展

常见问题

1、i2c 每次读写数据前都需要 setup 一次吗?

不需要

正常的业务逻辑为:

i2c.setup

…此处可以多次读写数据

i2c.close

setup 之后,只要没有 close,就可以反复读写数据

一旦执行了 close,下次读写数据前,必须再次 setup

2、i2c 通信时模块可以做从设备吗?

注意:模块 I2C 只能做主设备,(虽然有内部上拉电阻,但是暂时还未实现软件配置)使用时需要外部上拉,在配置 FAST 速率时,上拉电阻阻值不要大于 4.7K。

3、i2c 设备 7 位的地址为 0x38 ,需要我手动转换到 8 位地址吗?

这里 i2c_addr 地址是 7bit 地址

如果 i2c 外设手册中给的是 8bit 地址,需要把 8bit 地址右移 1 位,赋值给 i2c_addr 变量

如果 i2c 外设手册中给的是 7bit 地址,直接把 7bit 地址赋值给 i2c_addr 变量即可