-
I2C总线
我们知道I2C是一种两线通信协议:一根时钟线SCL,一根双向数据线SDA;所有通信以开始条件(SCL为高期间SDA上的下跳变)启动和结束条件(SCL为高期间SDA上的上跳变)来停止;发送器件改变SDA线上的数据只能在SCK为低期间,接收器件则在SCK为高期间接收SDA上的数据。同一I2C总线可有多个I2C器件,一个作为主节点,其余作为从节点,主节点通常是微处理器/控制器,从节点可以是各种外围器件如存储器、时钟、温度传感器等。
I2C总线最多可接6~8个I2C器件,这主要是基于器件的驱动能力的考虑,通常的作法还应在SCL和SDA线上加一个上拉电阻,阻值大小视总线上所有器件的总电容而定,一般为1K~10K。
-
从节点地址和响应
主节点控制I2C总线上的所有通信,可实现分明对不同从器件的访问。对器件的区分是通过从节点的地址来实现,从节点地址一般由4位器件代码和3位硬件地址码构成,常见的器件代码见下表:
器件类型
|
器件代码
|
器件实例
|
数字电位器
|
0101
|
X9221
|
温度传感器
|
1001
|
AD7416
|
AD\DA
|
1001
|
PCF8591
|
存储器
|
1010
|
X24C16
|
电源监控
|
1011
|
X4043
|
实时时钟
|
1101
|
X1203
|
硬件地址码通常是由器件的地址设置引脚来确定,但也有的器件没有这种引脚,那么从节点地址中硬件地址码则是固定值。
无论是主器件还是从器件,在发送完8位数据后会释放数据线SDA,作为接收的器件则在随后的第九个时钟期间将SDA拉低以响应接收到8位数据。
从节点检测到总线上开始条件后,开始接收从节点地址,与内部器件代码和硬件地址进行比较:如果相同则发出响应信号,并开始接收后面的数据直到收到一个停止信号,器件重新回到最初的空闲状态;如果不同则从器件不作任何响应也不会接收后面的数据。
-
X1203为什么会和24LC16冲突
我们先从X1243谈起,X1243内部既有时钟又有存储器,它的器件代码有两个,分别为1101和1010,没有硬件地址码设置,它的地址码部分固定为111。见下表:
再来看24LC16,它的器件代码也是1010,虽然24LC16有硬件地址设置引脚A0、A1、A2,但实际上芯片内部并没有连接。它的地址码部分用来选择块号,三位可选择000~111共8个块。见下表:
所以在X1243和24LC16共用I2C总线时,一旦访问24LC16的最高块号就会发生冲突,X1243和24LC16都会对从节点地址(1010111)作出响应,访问操作就会失败。
那么X1203应该不会与24LC16冲突,因为X1203内部没有存储器。但实验结果却证明仍存在冲突,为什么?唯一的解释是XICOR公司在制作X1243和X1203时使用了相同的电路来设计WAFER,仅有的区别是X1203没有设计内部存储器部件。但是由于二者的控制和时钟部件都完全相同,所以X1203对访问存储器的命令序列(1010111)同样会响应(实验已证明了这一点),当然不会读出任何实际内容更不会写入数据。
-
解决办法
产生上述问题是非常偶然的,第一,X1203采用了X1243的控制部件;第二,24LC16没有硬件地址码。所以解决问题的办法很多,只要避免其中任何一个条件即可:
方法一、使用一片X1243代替原来的X1203加24LC16;
方法二、使用带有硬件地址码的存储器,如X24164(16K位)
方法三、建议XICOR对X1203控制部件作更改(这个方法有点难)
注意,在使用方法二时,千万不要把X24164的硬件地址设置为111,不然的话灾难又会重演。
-
I2C总线使用要点