1.硬件电路
I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。如下图:
SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,需通过上拉电阻接电源VCC.当总线空闲时.两根线都是高电平。
2.i2c协议规则
传输过程如下:
主控发送start讯号(S)
主控发送从设备地址(slave dev addr)
主控发送方向(W/R)
从设备应答(ack)
主控(or从设备)发送数据(data)
从设备(or主控)应答(ack)
…
主控发送停止讯号(P)
下图是具体的s3c2440 一次i2c读写过程:
2.1 start & stop讯号
start信号:SCL是高电平,SDA被主控拉低
stop信号:SCL是高电平,SDA被主控拉高
2.2 ack讯号
第9个时钟周期,SDA被拉低表示ack讯号
2.3 DATA格式
用 9个clk传输8bit数据(7bit 从设备地址 + 1bit方向 ),MSB高位先出。第9个clk是ack讯号。
2.4 数据有效性
SDA 线上的数据必须在SCL高电平周期保持稳定,在 SCL 低电平时才能允许改变。
换言之,SCL为高电平时表示有效数据,SDA为高电平表示“1”,低电平表示“0”;SCL为低电平时表示无效数据,此时SDA会进行电平切换,为下次数据表示做准备。
2.5一次数据传输
2.6 一条SDA上实现双向传输的原理(开极电路)
条件:
1.主设备发送时,从设备不发送(通过SCL控制即可,比如让前8个clk主控发送数据到SDA,让第9个clk从设备发送数据到SDA)
2.主设备发送数据时,从设备的“发送引脚”不能影响SDA数据。反之,从设备发送数据时,主设备的"发送引脚"不能影响到SDA数据。那么如何做到?(SDA内部电路用三极管,开集电路)
从上图得出当A,B都为低电平时,三极管不导通,SDA的电平取决于外部电路,这里SDA有上拉电阻,所以对应高电平
当主控拉高A时,三极管导通,此时SDA接地,电平被拉低
同理,当从设备拉高B时,三极管导通,此时SDA接地,电平被拉低
那么电平真值表如下:
所以,实现双向传输时:
如果是master-> slave进行数据传输,那么让主控驱动三极管,拉低SDA。
如果是slave-> master进行数据传输,那么让从设备驱动三极管,拉低SDA。
否则,都不驱动三极管,SDA一直输出高电平,处于idle状态
从下面的例子可以看看数据是怎么传的(实现双向传输)。
举例:主设备发送(8bit)给从设备
⚫ 前 8 个 clk
◼ 从设备不要影响 SDA,从设备不驱动三极管
◼ 主设备决定数据,主设备要发送 1 时不驱动三极管,要发送 0 时驱动三极管
⚫ 第 9 个 clk,由从设备决定数据
◼ 主设备不驱动三极管
◼ 从设备决定数据,要发出回应信号的话,就驱动三极管让 SDA 变为 0
从这里也可以知道 ACK 信号是低电平从上面的例子,就可以知道怎样在一条线上实现双向传输,这就是 SDA 上要使用上拉电阻的原因。
为何 SCL 也要使用上拉电阻?在第 9 个时钟之后,如果有某一方需要更多的时间来处理数据,它可以一直驱动三极管把 SCL 拉低。
当 SCL 为低电平时候,大家都不应该使用 IIC 总线,只有当 SCL 从低电平变为高电平的时候,IIC 总线才能被使用。当它就绪后,就可以不再驱动三极管,这是上拉电阻把 SCL 变为高电平,其他设备就可以继续使用 I2C 总线了。
2.6 SCL被从设备拉低表示busy状态
在第9个clk 后i2c会产生中断,此时SCL被拉低,表示busy状态,表示谁都不允许再使用i2c, 然后等到中断处理结束了,也就是处于idle状态了,此时会释放出SCL,那么主控可以继续发送SCL讯号表示可以继续进行i2c通信了。