I2C 总线
一、I2C 总线的核心目的
I2C 总线是一种用于短距离设备间通信的串行总线,主要解决 “主控芯片与外设(如传感器、OLED 屏)之间的数据传输” 问题。
例如:STM32 单片机(主机)通过 I2C 总线读取 SHT20 温湿度传感器(从机)的数据,再通过 UART 发送到 PC 端显示。
二、I2C 总线基础概念
- 定义:串行、同步、半双工总线(飞利浦设计),仅需 2 根线(SCL 时钟线、SDA 数据线),均为双向。
- 硬件必备:SCL 和 SDA 需外接上拉电阻(作用:空闲时保持高电平,稳定电路)。
- 通信速率:低速 100Kbps、中速 400Kbps、高速 3.4Mbps(常用中低速)。
- 主从模式:支持单主机多从机(最常用)或多主机多从机。
- 主机:主动发起 / 结束通信(如 STM32);从机:被动响应(如传感器)。
- 设备地址:每个从机有唯一 7 位地址(如 SHT20 的地址为 0x40),用于主机识别目标设备。
三、硬件连接示例(单主机多从机)
- 主机:STM32U575RIT6
- 从机:SHT20(温湿度,0x40)、MAX30102(心率,地址另设)等
- 连接方式:所有设备的 SCL 引脚相连,SDA 引脚相连,各自接 3.3V 和 GND,SCL/SDA 线接 10KΩ 上拉电阻到 3.3V。
四、关键时序(通信的 “语法规则”)
1. 起始信号(S)与终止信号(P)
- 起始信号(S):SCL 高电平时,SDA 从高→低(下降沿),标志通信开始(仅主机产生)。
- 终止信号(P):SCL 高电平时,SDA 从低→高(上升沿),标志通信结束(仅主机产生)。
- 例:主机想和 SHT20 通信,先发送起始信号 “唤醒” 总线。
2. 数据传输时序
- 数据以字节(8 位)为单位传输,每 bit 需 1 个时钟周期(SCL 高 + 低)。
- 发送数据:SCL 低电平时,SDA 可改变(发送器写数据)。
- 接收数据:SCL 高电平时,SDA 需稳定(接收器读数据)。
- 例:发送 “0x40” 时,SCL 每低一次,SDA 依次输出该字节的 8 位(从高位到低位)。
3. 应答信号(ACK/NACK)
- 每传输 1 字节后,第 9 个时钟周期需回复应答:
- ACK(0):接收器确认收到数据;
- NACK(1):接收器未收到或结束通信。
- 例:主机给 SHT20 发完地址后,SHT20 回复 ACK 表示 “我在”。
4. 寻址信号(找目标设备)
- 主机发送 7 位从机地址 + 1 位读写位(W=0 写,R=1 读),凑成 8 位。
- 例:主机想读 SHT20(地址 0x40),寻址信号为
(0x40 << 1) | 1 = 0x81
;想写则为0x80
。
五、通信协议格式(实际 “对话流程”)
示例 1:主机从 SHT20 读取温度数据(单字节)
- 主机发起始信号(S);
- 主机发寻址信号(0x80,写方向,找 SHT20);
- SHT20 回复 ACK;
- 主机发 “读取温度” 命令(寄存器地址 0xE3);
- SHT20 回复 ACK;
- 主机发起始信号(重新开始);
- 主机发寻址信号(0x81,读方向);
- SHT20 回复 ACK;
- SHT20 发送温度数据(8 位);
- 主机回复 NACK(表示 “够了,结束”);
- 主机发终止信号(P)。
示例 2:为什么读数据需要 “先写后读”?
- 第一步 “写”:主机先告诉 SHT20“我要和你说话(地址),并要读你的温度寄存器(0xE3)”;
- 第二步 “读”:确认 SHT20 准备好后,主机再读取该寄存器的数据。
六、实战:SHT20 温湿度传感器应用
- 设备地址:7 位地址 0x40(寻址信号写 0x80,读 0x81)。
- 关键寄存器:
- 温度测量:0xE3(hold 模式,单主机);
- 湿度测量:0xE5(hold 模式)。
- 精度设置:默认温度 14 位、湿度 12 位(可通过用户寄存器修改)。
- 数据转换公式:
- 温度:
T(℃) = -46.85 + 175.72 × (温度数字量 / 65536)
- 湿度:
RH(%) = -6 + 125 × (湿度数字量 / 65536)
- 温度:
总结
I2C 总线的核心是 “通过时序和地址实现设备间有序通信”,理解起始 / 终止信号、应答机制、寻址规则是关键。实际应用中,需结合具体设备的地址和寄存器手册,按协议格式编写读写代码(如 STM32 通过 GPIO 模拟时序或使用硬件 I2C 外设)。