I2C协议及使用简析
简介
I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
i2c设备使用7位地址,协议也支持10bit,但是很多设备仅响应7bit地址,因此总线上最多有127个设备。
从硬件上来说,只有两条线,十分简单,所以很多设备都使用这种协议。通过控制两条线的时序来传递数据。总线上可以挂接很多设备,那么主设备怎么找到对应的从设备呢?
每一个从设备都有一个自己的地址,访问时遵守i2c总线协议,以eeprom为例:高4位固定,三位A0,A1,A2(由设备在板子上的连接确定的。),最后一个读写位这个地址由从设备和开发板连线决定的。
1k/2KA0,A1,A2 板子上的连线决定
4KA2,A1,P0
8KA2,P1,P2
16KP2,P1,P0 分页访问
因为s5pv210处理器集成了i2c的控制器,所以我们只需要给几个寄存器赋值就可以使用了,但是有的cpu没有集成i2c控制器,那么怎么办?
1外接一个控制器
2用两个gpio模拟时序输出
定义
I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
i2c(IIC)通信协议
定义: I2C 两线式串行总线
SCL: 时钟线
SDA: 数据线
协议
使用到的信号:
开始信号:start, 当SCL处于高电平,SDA产生一个下降沿
结束信号:stop, 当SCL处于高电平, SDA产生一个上升沿
应答信号:ACK,当SCL处于高电平, SDA为低电平状态
数据0/1(见图i2c——data): SDA低/高 ,如果发送1,SDA要在SCL低电平的时候跳变成高,然后在SCL高电平的时候保持高电平就是1;如果发送0,SDA要在SCL低电平的时候跳变成低电平,然后在SCL高电平的时候保持为0,前8个周期发送8个bit,第8bit为读写位,所以实际上发送的偏移地址只有7bit,比如我们要向一个slave ID为0x60的从设备读写,实际上发送的偏移地址是0x30,i2c的驱动会将这个偏移地址或上0/1,由cpu发送,第9个周期cpu把I2C线让出来,这时设备向cpu发送一个ACK信号,表示已经收到了。如果没有发送ACK信号,即第9周期时SDA为高电平,那么主设备知道发送的信号没有收到。
特点
i2c通信的特点:
i2c通信过程中,设备之间有主从之分。
i2c通信的发起者是主设备,总线上只有一个主设备,可以有很多从设备
i2c总线上的每个从设备都有一个固定的地址
用i2c协议与EEPROM通信
写过程: 产生一个start
从设备地址 + W
等待ACK
发送即将写入从设备内的偏移地址
等待ACK
发送即将写入从设备内的数据
等待ACK
产生停止信号
这个过程在用户态可能会产生回写 因为是8bit写,写完8bit后,回写了,例如写 7:1 8:2 9:3 10:4 ,但是在从设备中7和8bit写上了,但是9和10 bit没有写上,而是写入了1和2bit。
读过程:
START
从设备地址+W //看后面的数据是要从从设备读还是写信号,这里将读哪里的内容的地址写到从设备中
等ACK
发送要读的从设备内的偏移地址
等待ACK
START
从设备地址+R
等待ACK
CPU接收SDA上的数据(8bits)
CPU如果想让从设备继续发送下一个字节数据,则CPU发送ACK
否则CPU不发送ACK,在第十个周期CPU发送停止信号
问题
i2c总线上的设备,cpu读取或者写的时候数据不对,是因为总线上写的速度跟不上应用层cpu的发送速度,导致数据丢失。
这是驱动的问题,不是应用的问题,可以在应用上加延时解决
如eepromself-timed write cycle(5 ms max) 说明写操作的时间间隔为5ms