I2C总线是两线式的串行总线,分别为SDA(数据线),SCL(时钟线),I2C为同步串行通信。 I2C的接收方和发送方都已SCL这根时钟节拍为基准进行数据的收发。这个是什么意思呢?
例如:51要向E2PROM发送一个数据(32),程序如下:
/* I2C总线写操作,dat-待写入字节,返回值-从机应答位的值 */
bit I2CWrite(unsigned char dat)
{
bit ack; //用于暂存应答位的值
unsigned char mask; //用于探测字节内某一位值的掩码变量
for (mask=0x80; mask!=0; mask>>=1) //从高位到低位依次进行
{
if ((mask&dat) == 0) //该位的值输出到SDA上
I2C_SDA = 0;
else
I2C_SDA = 1;
I2CDelay();
I2C_SCL = 1; //拉高SCL
I2CDelay();
I2C_SCL = 0; //再拉低SCL,完成一个位周期
}
I2C_SDA = 1; //8位数据发送完后,主机释放SDA,以检测从机应答
I2CDelay();
I2C_SCL = 1; //拉高SCL
ack = I2C_SDA; //读取此时的SDA值,即为从机的应答值
I2CDelay();
I2C_SCL = 0; //再拉低SCL完成应答位,并保持住总线
return ack; //返回从机应答值
}
那么51作为主机,首先要拉低SCL,当低电平时,才允许给SDA赋值,即向总线写数据(在起始信号函数中,SCL已经被拉低了,所以下图中第一次不需要SCL=0这句),下来判读发送的数据从高到低,每一位是1还是0,是1,就将SDA拉高,是0,则将SDA拉低。此时SDA为一个新的状态值。然后先拉高SCL再拉低。那么此时就会有一个脉冲出现,这个脉冲作用在E2PROM上,会致使E2PROM就会去读SDA的状态并将其保存在内部的某个地方。如此循环八次,就将要发送的数据全部发送出来了。在8个脉冲的作用下,E2PROM也将数据全部读出来了。
下来,一但E2PROM接收完数据,就会发送一个0/1给51。0/1代表应答位(有时代表有是否有地址存在,有时代表写入成功与否)。
I2C_SDA = 1; //8位数据发送完后,主机释放SDA,以检测从机应答
我们来看上面这句,为什么SDA=1代表主机释放SDA。这是因为I2C上面器件都是“线与”的关系,意思就是所有接入器件 保持高电平,这条线才是高电平,只要有一个为0,那么这条线就为0。所以SDA=1;就代表着释放这根线。
上述就是I2C的写数据过程,主要理解时钟线是怎么配合着数据线进行数据传送的。读过程也很类似,给一个脉冲,E2PROM(从机)就会将SDA的状态更改一次,我们只要执行DAT=SDA就可以将从机发出来的状态值读出来。
SCL只所以叫时钟线,原因就是在这里,每产生一个脉冲,从机会自动进行一次读取,脉冲的产生又由主机产生,这样就达到了同步的效果,所以I2C通信的本质为同步串行通信。