时序
I2C 总线:规矩多的“老学究”
I2C 是半双工,只有两根线(SDA 数据,SCL 时钟)。它的时序非常讲究“信号”,所有的动作都在这一根 SDA 线上完成。
1. 起始信号 (Start) & 停止信号 (Stop)
这是 I2C 最独特的特征,只有在这两个时刻,SDA 才允许在 SCL 为高电平时变化。
- 起始 (Start):
- 状态:SCL 保持 高电平。
- 动作:SDA 从 高 -> 低 (下降沿)。
- 含义:“所有人注意,我要开始讲话了!”
- 停止 (Stop):
- 状态:SCL 保持 高电平。
- 动作:SDA 从 低 -> 高 (上升沿)。
- 含义:“通话结束,挂断。”
2. 写数据时序 (Write Sequence)
流程:Start -> 设备地址(写) -> ACK -> 寄存器地址 -> ACK -> 数据 -> ACK -> Stop
- 关键点:
- 设备地址:7位地址 + 第8位是 0 (0 代表 Write)。
- ACK (应答):每发完8位数据,主机必须释放 SDA (拉高),然后从机把 SDA 拉低,表示“我收到了”。如果从机不拉低(NACK),说明出错了。
3. 读数据时序 (Read Sequence) —— 这里有坑!
流程:Start -> 设备地址(写) -> ACK -> 寄存器地址 -> ACK -> Restart -> 设备地址(读) -> ACK -> 数据 -> NACK -> Stop
为什么要 Restart?
- 因为你想读某个寄存器,必须先“写”过去告诉它是哪个寄存器。所以前半段是“写模式”。
- 发完寄存器地址后,不能 Stop,而是直接再发一个 Start (叫 Repeated Start),然后发送设备地址 + 第8位是 1 (1 代表 Read)。
为什么要 NACK?
- 这是 I2C 的反直觉之处!主机读完最后一个字节数据后,必须发送 NACK (不拉低 SDA),告诉从机:“我读完了,不要再发了”,然后发送 Stop。
| 特征 | I2C (IIC) | SPI |
|---|---|---|
| 开始信号 | SCL高时,SDA 下降沿 | CS 拉低 |
| 结束信号 | SCL高时,SDA 上升沿 | CS 拉高 |
| 读/写控制 | 靠地址字节的最后1位 (0写/1读) | 靠发送具体的指令字节 (如 0x03 读) |
| 数据采样 | SCL高电平期间保持数据稳定 | SCK 的上升沿或下降沿(看模式) |
| 应答机制 | 必须有 ACK/NACK (第9个时钟) | 无硬件应答 (发出去就不管了) |
| 空闲状态 | SDA 和 SCL 都是高电平 (上拉电阻) | CS 高,MOSI/MISO/SCK 看配置 |