串行的8 位双向数据传输位速率在标准模式下可达100kbit/s 快速模式下可达400kbit/s 高速模式下可达3.4Mbit/s
总线信号
SDA:串行数据线
SCL:串行数据时钟
总线空闲:
SDA: 高电平
CLK: 高电平
开始信号:
SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
I2C的应答信号ACK:
Master每发送完8bit数据后等待Slave的ACK。
即在第9个clock,若从IC发ACK,SDA会被拉低。
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:
基本工作原理:
以启动信号START来掌管总线,以停止信号STOP来释放总线;
每次通讯以START开始,以STOP结束;
启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R. /W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
i2c发送时序是先发高位再发低位。
数据传送
写:SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化,SCL线呈现高电平期间,从机从总线上读取数据,clk再次被拉低时,从设备认为此位已读取完毕,认为是有效位。
只有在SCL线为低电平期间,SDA上的电平允许变化,SCL线呈现高电平期间,主机从总线上读取应答位。
写时序
写:SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化,SCL线呈现高电平期间,从机从总线上读取数据,clk再次被拉低时,从设备认为此位已读取完毕,认为是有效位。
只有在SCL线为低电平期间,SDA上的电平允许变化,SCL线呈现高电平期间,主机从总线上读取应答位。
发出开始信号之后,设备在数据未准备好时,拉低SCL线,这样主设备可知从设备未发送数据,从设备在数据准备好,可以发送的时候,停止拉低SCL线,这时候才开始真正的数据传输
从主机角度看一次写入过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输地址数据低字节,对于1字节地址段器件,传输待写入的数据
h. 设置SDA为输入三态,读取从机应答信号。
i. 对于两字节地址段器件,传输待写入的数据(2字节地址段器件可选)
j. 设置SDA为输入三态,读取从机应答信号(2字节地址段器件可选)。
k. 主机产生STOP位,终止传输。
读时序
读操作:主设备发送IC地址和寄存器地址,这两个字节的校验位都是由从设备来拉低; 从设备开始向从设备发送数据,clk为低时,sda变化,主设备clk拉高时读取sda, 校验位由主设备拉低; 当从设备发送完最后一个字节后,主设备强制把校验位拉高,告诉从设备不要需要再发了, 从设备发现这个校验位没有被拉低,认为主设备接收错误,也就结束发送了,当然了,从设备自己知道是最后一个字节。
从主机角度看一次读取过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输低字节地址数据,对于1字节地址段器件,无此段数据传输。
h. 主机发起起始信号
i. 主机传输器件地址字节,其中最低为1,表明为写操作。
j. 设置SDA为输入三态,读取从机应答信号。
k. 读取SDA总线上的一个字节的数据
l. 产生无应答信号(高电平)(无需设置为输出高点片,因为总线会被自动拉高)
m. 主机产生STOP位,终止传输。
- 并非每传输8位数据之后,都会有ACK信号,有以下3中例外
- 当从机不能响应从机地址时(例如它正忙于其他事而无法响应IIC总线的操作,或者这个地址没有对应的从机),在第9个SCL周期内SDA线没有拉低,即没有ACK信号。这时,主机发出一个P信号终止传输或者重新发出一个S信号开始新的传输。
- 如果从机接收器在传输过程中不能接收更多的数据时,它不会发出ACK信号。这样,主机就可以意识到这点,从而发出一个P信号终止传输或者重新发出一个S信号开始新的传输。
- 主机接收器在接收到最后一个字节后,也不会发出ACK信号。于是,从机发送器释放SDA线,以允许主机发出P信号结束传输。
DEBUG的时候可能出现的问题:
- 读出的ACK位为高,有可能是SDA位没有被拉低
- 可能是时间太快了,再加上SDA位有一个上拉电阻, 导致从设备发送ACK位低时,总线上的SDA位直接被拉高了,所以主设备读取到的ACK位永远为高。