IIC 通讯

写这篇文章的原因是本来我觉得IIC,SPI这种级别的协议早已了然于胸,直到今天在github被别人提醒,我才明白以前对着代码和各种中文资料知道的只是能凑合通讯,实际的规范中还有亿点点细节o.o

有点懒,基本协议内容就不再描述了(如果不了解可以看下下面规范原文),下面部分说明直接机翻

规范位置

比较重要的协议一览

  • 除了与高速模式相关的一种特殊情况外,不允许 I2C 设备驱动总线,即通过在总线上施加电压来发送 1。
    • 总线终止于高电平
  • Clock Stretching(不是所有从机都有这个功能,没有的话可以不实现)
    • 任何IIC总线设备(各个从机或主机)都可以要求延长SCL低电平时间甚至暂停通讯。
    • 规范中不包含等待超时(但是驱动中可能会有)
    • 一些从设备在超时一段时间之后会认为总线空闲
    • 这个功能对总线带宽有影响,使用时应当充分评估
    • 仅在 ACK 位之后(并且在下一个字节的第一个位之前)才允许在高速模式下进行时钟延长。位 2-9 之间的拉伸是非法的,因为这些位的边缘通过额外的电流源被提升。
  • i2c level shifting
  • Arbitration(单主机模式可以不实现)
    • 虽然看到协议想起来确实有这么回事,但是一般凑合用的时候就没实现过 😄
    • 能够遵循仲裁逻辑。如果两个设备同时开始通信,则向总线(或速度较慢的设备)写入更多零的设备赢得仲裁,而另一个设备立即停止总线上的任何操作。(这个没用过)
    • 总线繁忙检测。每个设备都必须检测正在进行的总线通信并且不得中断它。这是通过识别总线通信并在开始通信之前等待停止条件出现来实现的。(这个比较常见)
    • 如果使用多主机,那么所有主设备都应支持multimaster功能。
  • I2C标准定义了0.3 Vcc的低电平阈值,0.7 Vcc的高电平阈值。
  • 广播呼叫使用I2C 地址 0寻址总线上的所有设备。
  • 为了兼容淘汰的C-Bus协议,保留地址(’0000001X’)。I2C 设备必须忽略发往该地址的消息。
  • 地址“0000010X”旨在将 I2C 设备与在同一总线上使用不同协议的设备互连。只有能够使用这些协议运行的 I2C 设备才能回复消息。 (这个不太懂)
  • 10-bit-addressing
    • 为了防止地址冲突,由于 7 位地址的范围有限,引入了新的 10 位地址方案。此增强功能可以与 7 位寻址混合使用,并将可用地址范围增加约十倍。在开始条件之后,前导“11110”引入 10 位寻址方案。第一个字节的最后两个地址位与八位连接整个 10 位地址的第二个字节。仅使用 7 位寻址的设备只会忽略带有前导“11110”的消息。
  • auto-increment
    • eeprom什么的地址自动递增是协议的一部分
  • 速度(精度不重要)
    • 100k – 龟速(我起的名字) standard-mode
    • 400k – 快速 Fast Mode
    • 1 M – Fast Mode Plus (大部分都能在此频率工作,不过建议以各个设备datasheet为准)
    • 3.4M – high speed mode
    • 5M 超快速模式 ultra-fast-mode
      • 单向通信,从机不再发送ack
      • 可以多主机,但是没有仲裁机制
      • 推挽驱动
      • 多个设备可以通过共享 I2C UfM 总线进行寻址。112 个节点可用。
      • 超快速模式总线主要集中在 LED 设备。
高速模式
  • PC debug
  • Repeated Start Condition
    • 在发送地址字节(地址和读/写位)后,主机可以发送任意数量的字节,然后是停止条件。除了发送停止条件之外,还允许再次发送另一个开始条件,后跟地址(当然包括读/写位)和更多数据。这是递归定义的,允许发送任意数量的开始条件。这样做的目的是允许在不释放总线的情况下对一个或多个设备进行组合的写/读操作,从而保证操作不会中断。
    • 无论在一次传输期间发送了多少个开始条件,传输都必须恰好由一个停止条件结束。