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 文档和工具:
- Air201模组使用固件:LuatOS 底层 core ,本 demo 使用的固件版本是:LuatOS-SoC_V2002_Air201.soc
- 本教程使用的 demo:https://gitee.com/openLuat/LuatOS-Air201/tree/master/demo/i2c/sht20
- 将固件和脚本烧录到模块中:Luatools 下载和使用教程 - 合宙模组资料中心
- 源码和固件已打包,如下所示: 点我,下载完整压缩文件包
- i2c-api地址
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 变量即可