发 帖  
原厂入驻New
[经验]

I2C总线:固件实现详细信息

2020-9-20 08:54:16  466 I2C总线
分享
8
典型交易

通过I2C进行通信的设备必须符合特定的事件顺序。每个事件都对应于控制时钟(SCL)和数据(SDA)线的某种方式。如上面“支持信息”文章中所讨论的,这两个信号是总线上的设备可以共享信息的唯一方式。我们将一个通信序列称为“事务”;这个词比“传输”更合适,因为每个事务都涉及传输的数据和接收的数据,尽管在某些情况下,唯一的接收数据是主机检测到的确认(ACK)或不确认(NACK)位。以下时序图显示了典型的I2C事务。

请注意以下几点:
  • 对应于时钟逻辑高电平部分的虚线提醒我们,逻辑高电平(对于SCL和SDA而言)是“隐性”状态-换句话说,信号通过上拉电阻自然地浮空到逻辑高电平。“显性”状态为逻辑低电平,因为仅当设备实际将其驱动为低电平时,该信号才会为低电平。
  • 事务以“起始位”开始。每个I2C事务必须以一个起始位开始,该位被定义为SCL为逻辑高电平时SDA的下降沿。
  • 事务以“停止位”结束,定义为SCL为逻辑高电平时SDA的上升沿。I2C事务必须以停止位结束;但是,如本文后面所述,在生成停止位之前可能会出现多个起始位。
  • 时钟为高电平时数据有效,时钟为低电平时状态改变;数字通信系统通常是边缘驱动的,因此在实践中,数据是在时钟的上升沿读取的,并在时钟的下降沿进行更新的。
  • 从最高有效位开始,一次一次交换信息,每个字节后跟一个ACK或NACK。
  • 您可能希望ACK由逻辑高电平指示,而NACK由逻辑低电平指示,但是情况并非如此。ACK为逻辑低电平,NACK为逻辑高电平。这是必需的,因为高电平是隐性状态-如果从站不起作用,则信号自然会向上浮动到NACK。同样,只有在设备可操作且准备好继续进行事务处理时,才可以发送ACK(由显性逻辑低电平指示)。
以下列表描述了上述事务中的事件顺序:
  • 主机产生一个起始位来启动事务。
  • 主机发送与要与之通信的从机相对应的7位地址。
  • 第一个字节区域中的最后一位是读/写指示器。如果主机希望从从机读取数据,则该位设置为逻辑高;如果要将数据写入从机,则设置为逻辑低。
  • 下一个字节是第一个数据字节。它来自主机还是从机,具体取决于读/写位的状态。像往常一样,我们有8位数据,从最高有效位开始。
  • 数据字节后跟一个ACK或NACK,如果是读事务,则由主机产生;如果是写事务,则由从机产生。根据通信设备的固件或低级硬件设计,ACK和NACK可能具有不同的含义。例如,主机可以使用NACK表示“这是最后一个数据字节”,或者如果从机知道要发送多少数据,则可以使用ACK确认成功接收到数据。
  • 事务以主机产生的停止位终止。

多少字节?
每个事务以相同的方式开始:起始位,地址,读/写,ACK / NACK。之后,可以从主机向从机或从机向主机发送任意数量的字节,每个字节后跟ACK或NACK。NACK可用作说“停止发送数据!”的一种方式。例如,主机可能希望从从设备(例如温度传感器)接收连续的数据流;每个字节后面都会有ACK,如果主机需要将注意力转移到其他字节,它可以对从机进行NACK并在准备就绪时开始新的事务。

不停地开始I2C协议允许进行“重复启动”条件。当主服务器使用一个起始位启动一个事务,然后通过另一个起始位启动一个新的事务而没有中间的停止位时,会发生这种情况,如下所示:

只要单个主服务器需要执行两个或多个单独的事务,就可以使用此功能。但是,在某些情况下,重复启动条件特别方便:
假设您有一个从设备将信息存储在一组寄存器中。您要从十六进制的0xA0寄存器地址160中检索数据。I2C协议不允许主机在单个事务中发送数据接收数据。因此,您必须执行写事务以指定寄存器地址,然后执行单独的读事务以检索数据。但是,这种方法可能会导致问题,因为主机会释放总线在第一个事务结束时,另一个主机可以要求总线,并阻止第一个主机获取所需的数据。此外,第二个主机可能与同一个从机通信并指定不同的寄存器地址。。。如果第一个主机随后要求总线并在不重新指定寄存器地址的情况下读取数据,它将读取错误的数据!如果第二个主服务器随后尝试在其“先写后读”过程中执行读事务,则最终也会得到错误的数据!这是一个等待发生的系统故障-幸运的是,重复的启动条件可以通过在 释放总线的情况下启动第二个(读取)事务来防止这种混乱:


当大师无法相处I2C如此通用的部分原因在于它对多个主机的支持。但是,正如上一节所展示的,大师们并不总是在一起玩得很好。设备的I2C逻辑必须能够确定总线是否空闲。如果另一个主控器要求使用该总线,则设备将等待直到当前交易结束后再启动自己的交易。但是,当两个(或多个)主服务器尝试同时启动事务时会发生什么?I2C为这个原本令人讨厌的问题提供了一种有效且出奇的简单解决方案。该过程称为“仲裁”,它依赖于I2C开漏总线配置的灵活性:如果一个主机尝试将信号逻辑驱动为高电平,而另一个主机将逻辑逻辑驱动为低电平,则逻辑低主机将“赢得, ”,此外,

该图传达了I2C仲裁的基础;该过程发生如下:
  • 两个主机都产生一个起始位并继续发送。
  • 如果主机恰好选择相同的逻辑电平,则什么也不会发生。
  • 一旦主机尝试施加不同的逻辑电平,将信号驱动为低电平的主机即为获胜者;失败者检测到逻辑不匹配并放弃其传输。
花一点时间来欣赏这种安排的简单性和有效性:
  • 获胜者将继续传输而不会中断-不会损坏数据,不会引起驱动程序争用,无需重新启动事务。
  • 从理论上讲,失败者可以在仲裁过程中监视从站地址,如果碰巧是被寻址的从站,则实际上可以做出适当的响应。
  • 如果竞争的主机都从同一个从机请求数据,则仲裁过程不会不必要地中断任何事务-不会检测到不匹配,并且从机会将其数据输出到总线,以便多个主机可以接收它。

结论
本文介绍了影响固件或底层硬件设计的重要I2C详细信息。如果你的微控制器包括专用的I2C或SMBus硬件,则一些实现细节将自动处理。这很方便,但肯定不是无知的借口,因为您仍然需要至少了解一点(可能更多一点)有关I2C真正如何工作的知识。此外,如果你发现自己被困在没有I2C外设的荒岛上,则此处提供的信息将使你在设计仅固件(也称为“位撞击”)I2C例程的过程中处于良好状态。

李红涛 2020-9-20 22:48:17
非常感谢分享。。。。。。
回复

举报

小明同学 2020-9-27 10:21:28
感谢感谢,,,,,,,,,,,,,,,,
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表