2、I2C协议详解:起始条件、停止条件、数据有效性、应答机制

各位同学,今天我们来啃I2C协议里最核心的四个概念。说实话,很多新手调不通I2C,往往就是这四个地方没吃透。我自己刚入行那会儿,也在这上面栽过跟头——有一次调试传感器,数据死活读不对,折腾了两天,最后发现是应答信号时序差了半个时钟周期。

好,咱们一个一个来拆解。

2.1 起始条件(S)与停止条件(P)

I2C总线在空闲时,SCL和SDA都是高电平。这是规矩,谁都不能违反。

起始条件:当SCL为高电平时,SDA从高电平跳变到低电平。这个下降沿告诉所有从机:「注意,主机要开始通信了!」

停止条件:当SCL为高电平时,SDA从低电平跳变到高电平。这个上升沿告诉所有从机:「本次传输结束,释放总线吧。」

我个人的习惯是,在写代码时把这两个条件封装成宏或内联函数。为什么?因为时序要求非常严格——SDA的跳变必须在SCL高电平期间完成,而且建立时间和保持时间都有明确要求。

关键点:起始和停止条件只能由主机产生。从机永远不能主动发起这两个信号。

我曾经在项目里见过一个坑:有人用GPIO模拟I2C时,在发送起始条件前忘了先把SCL拉高,结果从机根本没识别到起始信号。嗯,这种低级错误,调试起来真的很浪费时间。

2.2 数据有效性

I2C的数据传输有个铁律:数据在SCL高电平时必须稳定,只有在SCL低电平时才能变化

你想想看,如果数据在SCL高电平时乱跳,接收方怎么判断你传的是0还是1?所以协议规定得死死的——SDA上的数据,只能在SCL为低电平时改变。

具体来说:

  • SCL高电平期间:SDA保持稳定,此时读取数据
  • SCL低电平期间:SDA可以变化,发送方准备下一位数据

每个字节传输8位数据,高位在前(MSB first)。我刚开始学的时候总记反,后来在代码里加了个注释才改过来。

小技巧:写模拟I2C驱动时,建议在SCL低电平时更新SDA,然后拉高SCL,延时一小段时间再读取SDA。这个顺序千万别搞反。

2.3 应答机制(ACK/NACK)

这是I2C协议里最巧妙的设计之一。每传输完一个字节(8位),接收方必须在第9个时钟周期给出应答信号。

应答(ACK):接收方在第9个时钟周期将SDA拉低,表示「收到,请继续」。

非应答(NACK):接收方在第9个时钟周期保持SDA高电平,表示「没收到」或「不想收了」。

为什么需要应答?说白了,就是让发送方知道数据有没有成功到达。我在调试一个气压传感器时,发现读出来的数据全是0xFF,后来用逻辑分析仪一看,从机一直在发NACK——原来是地址写错了。

场景 应答信号 含义
主机发送地址后 ACK 从机存在且准备好通信
主机发送地址后 NACK 从机不存在或忙
主机发送数据后 ACK 从机成功接收
主机接收数据后 ACK 主机还要继续读
主机接收数据后 NACK 主机不再读了(停止信号前)
注意:应答信号是由接收方拉低SDA,但SCL时钟仍然由主机提供。很多新手以为应答时钟也是接收方产生的,这是误解。

2.4 完整的数据传输流程

把上面四个概念串起来,一次完整的I2C传输是这样的:

  1. 主机发送起始条件(S)
  2. 主机发送7位从机地址 + 1位读写位(共8位)
  3. 从机在第9个时钟回复ACK
  4. 主机发送/接收数据字节(每字节后跟ACK/NACK)
  5. 主机发送停止条件(P)

我画了一张流程图,把整个逻辑串起来,你一看就明白了:

I2C 单字节写传输流程 起始条件 (S) 从机地址 (7位) + 读写位 (1位) ACK (从机) 数据 (8位) ACK (从机) 停止条件 (P) 注:读操作时,最后一个数据字节主机回复 NACK 后再发停止条件 SCL ──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬── SDA ──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──

2.5 避坑指南

最后分享几个我实际项目中踩过的坑:

  • 起始条件重复发送:有些从机在收到起始条件后需要一定时间准备,连续快速发送起始条件可能导致从机漏掉。我建议在起始条件后加一个微秒级的延时。
  • 应答超时处理:不要死等从机回复ACK。我曾经在一个项目里没加超时判断,从机挂了之后总线就卡死了。加个超时机制,比如等待500μs没收到ACK就报错重试。
  • 停止条件后的释放时间:停止条件发出后,主机应该释放SDA和SCL(设置为输入或开漏输出高电平),给从机留出处理时间。我一般会加5μs的延时再开始下一次通信。
我的经验:调试I2C时,逻辑分析仪是最好的工具。别靠猜,直接抓波形看起始条件、数据、应答的时序对不对。省下的时间够你喝好几杯咖啡了。

好了,I2C协议的这四个核心机制就讲到这里。记住:起始和停止条件是骨架,数据有效性是血肉,应答机制是灵魂。把这三点吃透了,I2C通信对你来说就是小菜一碟。


专注资料整理