特点
- 两根线 SCL SDA
- 同步、半双工
- 带数据应答
- 支持总线挂载多设备 一主多从 多主多从
两个功能:
- 读取外设模块指定位置的寄存器
- 写外设模块指定位置的寄存器
一个完整的通讯协议一定是在软件和硬件上同时定义的。
硬件
- 所有的I2C设备的时钟线与数据线都要连在一起
- 设备的SCL和SDA均要配置成开漏输出模式
因为I2C是半双工,时钟线SDA既要输出也要输入,不能单独的设置成推挽输出或者开漏输入。
- 时钟和数据线都要加一个上拉电阻 4.7KΩ左右
内部结构框图:
输入没有影响,时钟和数据都可以直接输入进去;
输出时,只能输出低电平,不能输出高电平,所以外挂一个电阻,进行弱上拉。
拿杆子和弹簧距举例子:
一根杆子,不能往上拉,只能选择往下拉,或者松手,上面加一根弹簧,往下拉时,低电平输出,松手时弹簧向上拉。
好处:
- 杜绝电源短路的现象;
- 避免引脚的频繁切换(开漏+弱上拉 兼具输入与输出的功能)
- 线于现象,从设备中只要有一个输出低电平,总线就是低电平
软件
基本时序单元
起始终止
起始条件:SCL高电平期间,SDA从高电平切换到低电平
终止条件:SCL高电平期间,SDA从低电平切换到高电平
数据 发送一个字节
SCL低电平期间,主机将数据依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,以此循环2次,即可发送一个字节。
而且同步的的好处,就算主机在发送的过程中,突然进中断了,SCL和SDA信号会不断地延长此时的状态,进行完终端之后,回来继续运行。
数据 接收一个字节
SCL低电平期间,从机将数据为依次放到SDA线上(高位先行),然后释放SCL,主机将从SCL高电平期间读取数据位,所以SCL高电平期间不允许SDA有数据变化,以此循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA,交由从机控制,也就是SDA前面一段实线到虚线的部分,从低电平到高电平)。
应答 发送应答
主机在接收完一个字节之后,在下一个时钟发送一个数据,数据0表示应答,数据1表示非应答。
应答 接收应答
主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)
时序
指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入数据(Data)
在指定设备1101 000 在指定地址0X19下,写下0XAA这个数据。
在应答位上,主机释放SDA为高电平;从机要应答,拉低SDA,所以根据线与的特性,为低。应答结束,从机放开SDA,为高电平。
当前地址读
对于指定设备Slave Address,在当前地址指针指示的地址下,读取从机数据Data。
这里有一个难点,指定获取数据的地址是谁?0X0F是怎么来的?也就是说当前地址指针是谁?
一般根据你前一个写入的地址+1,作为当前地址指针。
正是因为这个问题,所以这个时序,不经常用。
指定地址读
对于指定设备(Slave Address) ,在指定地址 (Reg Address) 下读取从机数据(Data)
该时序又称为复合时序,把指定地址写,还没来得及写的时序,加上当前地址读的时序。
先起始,再重复起始,再停止。