我最近的项目要求使用i2c通信,使用一个带有多个从设备的主设备。我知道,对于主设备发送的每个数据字节(实际数据),从设备会用Nack\Ack(1,0)进行响应。我对Nack和ACK的解释感到困惑。我在网上搜索了一下,但没有弄清楚这件事。我的理解是这样的。
确认-我已成功接收到数据。给我发送更多数据。NACK-我还没有收到数据。再次发送。是这样的事情还是我错了。请澄清并提出正确答案。
谢谢Amit kumar
您确实应该阅读这里的I2C规范,但简单地说,ACK/NACK有两种不同的情况需要考虑:
-
发送从机地址后:当I2C主机发送要与之交谈的从机地址(包括读/写位)时,识别其地址的从机发送ACK。这告诉主人,它试图接近的奴隶实际上在公共汽车上。如果没有从设备识别该地址,则结果是NACK。在这种情况下,主机必须中止请求,因为没有人可以与之交谈。这通常不能通过重试来解决。
-
在传输中:读取字节的一侧(接收时的主端或发送时的从端)接收到字节后,必须发送ACK。主要的例外是,如果接收器控制发送的字节数,则它必须在要发送的最后一个字节之后发送NACK。例如,在从机到主机的传输中,主机必须在发送STOP条件以结束传输之前发送NACK。(这是规范要求的)
也可以是,如果存在错误,则接收机可以发送NACK;我不记得规范是否允许这样做
但底线是,NACK要么指示无法重试的致命情况,要么只是指示传输结束。
BTW,接收设备需要更多时间进行处理的情况从未由NACK指示。取而代之的是,一个从设备要么";时钟拉伸";(或者主机只是延迟生成时钟),或者它使用更高层的协议来请求重试。
编辑6/19/19:正如@DavidLedger所指出的,有些I2C闪存设备使用NACK来指示闪存内部繁忙(例如完成写入操作)。我回到I2C标准(见上文),发现了以下内容:
有五种情况会导致NACK的产生:
总线上不存在具有传输地址的接收器,因此没有设备响应确认。
接收器无法接收或发送,因为它正在执行某些实时功能,并且尚未准备好启动与主机通信。
在传输过程中,接收器会获得它不理解的数据或命令。
在传输过程中,接收器无法再接收任何数据字节。
主接收机必须向从发射机发送传输结束的信号。
因此,根据标准,这些NACK条件是有效的。
短延迟,特别是在单个操作中,通常会使用时钟拉伸,但较长的延迟,特别在操作之间,以及无效操作之间,我的井会产生NACK。
I2C协议以起始位开头,后跟从地址(7位地址+1位用于读/写)。发送从属地址后,Master释放数据总线(SDA线),将线路置于高阻抗状态,让从属设备驱动线路。
如果地址与从机地址匹配,则从机将ACK的线路拉低。如果线路没有被任何从设备拉低,则主设备将其视为NACK,并在下一个时钟脉冲中发送停止位或重复开始位,以终止或重新启动通信。
除此之外,每当接收器不能通信或理解数据时,也发送NACK。
NACK还被主控器(接收器)用来在其具有跟随停止位的所有数据之后终止读取流。