i2c - I2c 总线上的 NACK 和 ACK 响应

标签 i2c serial-communication communication-protocol

我最近的项目需要使用 i2c 通信,使用单个主设备和多个从设备。我知道,对于主机发送的每个数据字节(实际数据),从机以 Nack\Ack(1,0) 响应。
我对如何解释 Nack 和 ACK 感到困惑。我搜索了网络,但我没有得到关于这个的清晰图片。我的理解是这样的。

ACK-我已经成功接收到数据。向我发送更多数据。
NACK-我还没有收到数据。再次发送。
这是这样的事情还是我错了。
请澄清并提出正确的答案。

谢谢
阿米特库马尔

最佳答案

你真的应该阅读 I2C 规范 here ,但简而言之,ACK/NACK 有两种不同的情况需要考虑:

  • 发送从机地址后:当 I2C 主机发送要与之通信的从机地址(包括读/写位)时,识别其地址的从机发送 ACK。这告诉主机它试图到达的从机实际上在总线上。如果没有从设备识别该地址,则结果为 NACK。在这种情况下,主人必须中止请求,因为没有人可以交谈。这通常不是可以通过重试来解决的。
  • 在传输中:在读取字节的一方(接收的主机或发送的从机)接收到一个字节后,它必须发送一个 ACK​​。主要的异常(exception)是,如果接收方正在控制发送的字节数,它必须在要发送的最后一个字节之后发送 NACK。例如,在从机到主机的传输中,主机必须在发送 STOP 条件以结束传输之前发送 NACK。 (这是规范要求的。)

  • 也可能是接收方有错误可以发送NACK;我不记得规范是否允许这样做。

    但最重要的是,NACK 要么表示无法重试的致命情况,要么只是表示传输结束。

    顺便说一句,接收设备需要更多时间来处理的情况永远不会由 NACK 指示。相反,从设备要么进行“时钟延长”(或者主设备只是延迟生成时钟),要么使用更高层的协议(protocol)来请求重试。

    2019 年 6 月 8 日编辑:正如@DavidLedger 所指出的,有些 I2C 闪存设备使用 NACK 来指示闪存内部繁忙(例如,完成写入操作)。我回到 I2C 标准(见上文),发现以下内容:

    There are five conditions that lead to the generation of a NACK:

    1. No receiver is present on the bus with the transmitted address so there is no device to respond with an acknowledge.

    2. The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.

    3. During the transfer, the receiver gets data or commands that it does not understand.

    4. During the transfer, the receiver cannot receive any more data bytes.

    5. A master-receiver must signal the end of the transfer to the slave transmitter.



    因此,这些 NACK 条件根据标准是有效的。

    短延迟,特别是在单个操作中,通常会使用时钟拉伸(stretch),但较长的延迟,特别是操作之间以及无效操作,我很可能会产生 NACK。

    关于i2c - I2c 总线上的 NACK 和 ACK 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37040696/

    相关文章:

    c - 在 Linux 上使用 I2C 读取/写入

    c - 为什么我只收到第一个地址字节? (I2C 协议(protocol))

    c++ - 从字符串中提取信息

    c - 将输出重定向到 linux 中的文件

    Python套接字,如何摆脱无限循环并处理异常

    .net - 观察.NET Remoting 应用程序之间通信的工具?

    c - 2`s complement in 3.13 format(取值范围是-4~3.99)是什么意思?

    c++ - 使用运算符进行 I2c 操作

    bash - 在 bash 中将十六进制字节发送到串行

    asynchronous - 现实世界中跨平台的分散式异步对等通信