旧乡故客
发表于: 2018-7-23 21:53:28 | 显示全部楼层

本系列文章主要介绍如何使用Silicon Labs微控制器的SMBus外设设计一个I2C接口。共包含两个部分:

●    第一部分:I2C的基本概念

●    第二部分:I2C设计示例实践


专用硬件

I2C是一种相对复杂的协议,需要详细的通信过程和特定的电路配置才能正常工作。尽管如此,I2C的应用仍然很普遍,正是由于其设计的复杂性,它可以在多个独立的集成电路之间实现灵活、强大、引脚数少的串行通信。确实,设计一个“纯底层”的I2C接口 - 即低级硬件或纯固件 - 会有点麻烦;但幸运的是,很多制造商的微控制器都集成了快速实现I2C的外设。在这篇两篇文章中,我们将详细讨论如何将I2C通信合并到专为EFM8微控制器编写的固件中,而且此处介绍的概念和代码适用于其他Silicon Labs器件。此外,将这些代码移植到任何其他的微控制器并不困难 - 毕竟,I2C是一种标准化协议,不会因制造商而异。


配置硬件

我们将使用SMBus外设实现I2C,SMBus外设同时支持这两种协议的(SMBus实际上是I2C的扩展)。微控制器通常用作I2C主控制器,因此我们将重点介绍I2C的主控功能,但也可以在类似的固件中实现从机功能。以下的图片截屏自Simplicity Studio软件,展示了SMBus外设的配置:

IC24_capture1.PNG


●     Timer0作为串行时钟源,然后配置Timer0为100 kHz的溢出频率。

●     使能SMBus外设。

●     在本篇文章中,我们希望保持I2C尽可能简单,因此“free timeout detection”、“SCL timeout detection”和“setup and hold time extension”都被禁用(您可以在EFM8参考手册中阅读这些功能的更多内容)。

●     启用“Slave inhibit”,因为在本文中,EFM8控制器仅用作主站。如果希望EFM8在总线上的另一个设备尝试将EFM8作为从设备进行寻址时产生一个中断,则需要禁用此功能。

●     Slave-address的属性没有更改,因为此示例不包含从机功能。如果希望EFM8作为从站而不是主站(或除主站之外),则必须设置主设备用于与EFM8建立通信的从地址。

●     “Hardware acknowledge”已禁用,但在许多情况下,启用它会更简单。使能时,当EFM8作为从机寻址或在主/读操作期间接收到一个字节时,SMBus外设将产生ACK或NACK而无需实时固件干预。

●     “start detection window hold time”功能允许您修改应用于检测起始位的时序规范。这可用于补偿时钟(SCL)和数据(SDA)线之间的多数阻抗不匹配。在大多数情况下,不需要这种补偿。


现在配置了外设,我们需要在交叉开关(crossbar)中启用SMBus0,以便将SCL和SDA连接到I / O引脚。两个引脚应配置为开漏输入/输出,如下所示:

IC24_capture2_2.PNG


如果您还启用了SPI外设,则此特定引脚分配显示哪些引脚将分配给SCL和SDA。


通信标志

根据I2C规范,I2C事务必须遵循特定的事件顺序。因此,Silicon Labs希望您以状态机的形式实现I2C通信并不奇怪:每个事件将固件从一个状态引导到另一个状态,并且在事务的每个阶段执行的代码由值确定状态变量。这很直观,但重要的是理解哪些可能不会立即显现的内容 - 即SMBus中断标志是状态机操作中的主导因素。中断标志的功能类似于交通信号灯,用于控制东西向的固件和南北向的硬件之间的交互:

●     SMBus硬件在事务中的每个事件之后都会置位中断标志。

●     当标志置位时,硬件将SCL保持在逻辑低电平,这实际上是“无效”时钟状态,因为当SCL为低电平时允许SDA转换。因此,只要设置了标志,总线就会“停滞”。

●     在此“停滞”状态下执行与I2C相关的固件;这种巧妙的安排可确保处理器在SCL的下一个上升沿再次激活之前完成其任务。即使是慢速处理器或冗长的固件程序也不是这种技术的问题,因为I2C协议被设计为支持扩展的时钟低周期。

●     必须通过固件清除SMBus中断标志;实际上,将标志位设置为零的操作是启动I2C事务中的下一个硬件事件的操作。这就是为什么清除标志位是在分配给状态机的每个部分的代码块中执行的最终命令。


流程图

Silicon Labs在其EFM8参考手册中提供了一些非常有用的状态机和事件序列图。让我们从主机/写操作开始:

IC24_datasheet1.PNG


该图标识了典型I2C事务中的每个事件及其相关中断;蓝色字母对应于相应的状态机流程图中描述的代码块(见下文)。所有数据字节都从主设备传输到从设备,因此每个ACK都由从设备生成。这就是无论硬件ACK是启用还是禁用,中断都是相同的 - 主机在主/写操作中不产生任何ACK。

IC24_datasheet2.PNG


(注意:在EFM8参考手册中的一些,可能全部中,该图有一个拼写错误,指示写操作时R / W位应设置为1而不是0。)仔细看看这个信息量很大的流程图。再次,注意事务中的每个硬件事件如何跟随中断,因此每个中断对应于从一个状态到另一个状态的转换。高效,干净,可靠的I2C代码的关键是由中断事件驱动的状态机:在设置中断标志时调用中断服务程序,然后使用switch语句执行与当前状态对应的代码块交易。每个代码块中的最后一个语句将中断标志位复位为零,从而启动下一个硬件事件。


以下是主机/读操作的事件序列:

IC24_datasheet3.PNG

注意产生中断的时间差:如果使能硬件ACK,则在主机(自动)根据SMBus控制寄存器中ACK / NACK位的预先存在状态生成ACK或NACK后产生中断;在这种情况下,固件所需的动作是存储接收的字节以准备下一个字节。如果禁用硬件ACK,则在接收到数据字节的最后一位后立即生成中断。 SMBus控制寄存器中的“ACK请求”位设置为指示需要固件干预,并且作为响应,固件应将适当的值写入ACK / NACK位。然后继续执行存储接收的字节并清除中断标志。


这是主机/读流程图:

IC24_datasheet4.PNG


注意与写入操作的不同点在于:1)设置R / W位为高电平而不是低电平; 2)主机从SMBus数据寄存器读取数据(而不是写入); 3)主设备控制ACK / NACK响应,以确认一个字节被成功接收(通过ACK)或指示不再需要数据(通过NACK)。 EFM8参考手册还提供事件序列和从站功能的流程图。


结论

我们介绍了EFM8控制器的SMBus / I2C外设的最重要的特性,并且还建立了设计高效、强大的I2C固件接口的基本概念。第2部分将更详细地探讨代码开发;同时将提供I2C主控功能的示例代码,并且我们还将查看SCL和SDA信号的示波器跟踪。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 29 | 回复: 32



手机版|

GMT+8, 2024-12-21 20:39 , Processed in 0.054397 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

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