概述
- I2C是双向二线制(SDA数据线和SCL时钟线)同步串行总线
- 同步:数据的传输是在一个共同的时钟信号控制下进行的,发送方和接收方都根据这个时钟信号来确定数据的发送和接收时机
- 串行:表示数据是一位一位依次传输的,而不是像并行总线那样多个数据位同时传输。串行传输方式减少了硬件引脚的数量,但传输速度相对并行传输来说可能会慢一些。
- 在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。
- 如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送。
- 如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下,主机负责产4生定时时钟和终止数据传送。
- 半双工
- SCL和SDA配置为开漏输出,都要加上拉电阻,一般4.7k(推挽可能会短路)
I2C时序基本单元
起始条件
- SCL高电平期间,SDA从高电平切换到低电平(空闲时刻由于上拉电阻都处于高电平)
终止条件
- SCL高电平期间,SDA从低电平切换到高电平
发送
- SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节
接收
- SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)
应答
发送应答
- 主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
接收应答
- 主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
设备地址
- 有7位和10位+1个读写位(0写1读)
- 地址出厂时高位一般是确定的,低位可通过某些引脚来改变
- 较常用的7位地址,2^7=128,但有些地址被保留了,所以理论上可以挂<128个从器件。
- 实际上,I2C 总线是一种开漏输出的通信方式,需要外接上拉电阻。总线电容是所有连接到总线上的设备引脚电容和线路电容的总和。随着连接设备数量的增加,总线电容也会增大。当总线电容过大时,信号的上升和下降时间会变长,可能导致信号失真,影响通信的可靠性。通信速率越高,实际可连接的设备数量可能就越少。实际上只在i2c上挂几个或十几个设备
I2C时序
指定地址写
- 对于指定设备(Slave Address),在指定地址(Reg Address))下写入指定数据(Data)
- 第一个字节是设备地址,第二个字节是设备寄存器地址
当前地址读
- 对于指定设备(SlaveAddress),在当前地址指针指示的地址下,读取从机数据(Data)
- 第一个字节是设备地址+读指令,但第二个字节不再是设备寄存器地址,发送完第一个字节后主机立马进入接收。因此要指定寄存器的话,要用到当前地址指针
- 当前地址指针:上电后默认指向0地址,每写入或读一个字节,指针会自动自增一次,读的时候没法指定那个地址,读的是当前这个指针指向的地址,由于不能指定,所以少用
指定地址读
- 对于指定设备(Slave Address),在指定地址(Reg Address)下读取从机数据(Data)
- 第一个字节是设备地址+写指令,第二个字节寄存器地址+读指令,这样成功使设备当前地址指针指向了目的寄存器,再来一个起始条件和设备地址读,就可以实现指定地址读了