在 Linux 中使用 I2C 总线
I2C 总线是一种双线串行总线,用于将各种 IC 连接到计算机或微控制器。它最初由飞利浦公司在 80 年代早期开发,但现在已获得众多公司的支持。
我第一次接触到这种总线是在我还使用旧的 Commodore C64 时,当时我在翻阅一些硬件书籍。我从未构建过适配器,所以就忘记了它,直到我开始研究 Linux 内核。那时我才想到构建一个适配器并编写相应的内核模块来将总线作为字符设备访问,这将是一个很有前景的目标。
I2C 总线由两条线组成,一条用于数据,一条用于时钟。芯片通过集电极开路输入/输出级连接到总线,这使得线路在空闲时保持高电平。
传输通过起始条件启动,之后传输一个地址字节。该字节由一个 7 位设备地址和一个方向位组成。如果从设备识别出自己的地址,它会确认传输。然后,可以向从设备传输任意数量的字节,直到最后一个字节未被确认。传输以停止条件结束。
数据与时钟线的高电平状态同步传输,此时数据信号的状态必须稳定。此规则仅在生成起始和停止条件时被打破,这两个条件封装了一次传输。传输速度不是固定的,但规范保证速度高达 100 kHz。如果设备无法应对传输速度,它可能会拉低时钟线,从而减慢进程。
在考虑数据传输速率时,我们因此只能假设最佳情况,因为没有下限。在 100 kHz(即 100 kbps)下,我们需要 2 位用于起始和停止,9 位用于地址(包括确认位),以及 18 位用于数据(如果我们想读取两个字节)。总而言之,加上传输间隙的额外一位,我们的有效数据采集速率为 100 k/30 bps,即每秒 3333 个样本。因此,可以看出 I2C 总线不能用于音频数据或其他高速应用,但它仍然足够快,可以轻松地调查传感器设备阵列并在毫秒内做出反应。
此外,总线的基本规范还有一些扩展。一种扩展是快速模式,它允许以高达 400 kHz 的速率传输数据。地址空间中的另一种扩展支持 10 位宽的标识符。Access.bus 在 I2C 总线硬件之上实现了一个软件协议,以便与计算机外围设备通信。
可用于总线的芯片涵盖了广泛的需求。最初,该总线是为计算机控制的电视机设计的,从而产生了各种调谐电路、彩色控制器和图文电视控制器。
如今,市场上也有几个微控制器系列提供直接的 I2C 总线支持,带有 A/D-D/A 转换器、电源开关、电子电位器和 LCD 显示驱动器。这些微控制器允许将较慢的外围设备连接到总线。
I2C 总线控制的 IC 也可用于电信服务,范围从寻呼机到 GSM 电话。使用这些服务可以轻松地通过寻呼机呼叫启动对计算机的操作。
当我开始尝试使用 I2C 总线时,我必须为我的 PC 构建一个适配器。连接它们的最简单解决方案涉及一个 TTL 芯片和几个电阻器。这个适配器占用了我的第二个并行端口,并且长期以来一直为我服务。
本质上,数据传输是通过控制线路的状态来完成的。这种类型的设备在许多类型的商业产品中也很常见,例如带有图文电视接收器的电视卡。
更复杂的解决方案涉及一个专用的适配器芯片,称为 PCF 8584。该芯片实现了大部分所需的协议,并提供了一些不错的附加功能,例如中断生成、总线监视和长距离模式。
最初,我只支持我自己的适配器,但我目前正在为其他适配器实现驱动程序。
通过 Linux 控制总线很简单。与字符设备一样,您只需打开设备文件,设置从设备地址(通过 ioctl 调用),然后读取或写入数据。根据适配器的不同,您可以设置不同的选项。
如果您不喜欢 C,我为 Tcl/Tk 编写了一个小扩展,它可以直接控制 I2C 总线,从而提供了一种舒适的可视化采集信息的方式。该扩展也是一个方便的总线调试接口。
目前在奥地利林茨学习计算机科学。可以通过 simon@tk.uni-linz.ac.at 联系他。