I2C的硬件电路如下:
只有两根线,一条时钟线,一条数据线
I2C的发送和读取的规则:
时钟线在高电平时,发送方发送数据,同时时钟线高电平时接收方接收数据
如果在一个I2C电路中,一个设备发出了高电平,而另一个设备发出了低电平,此时会发生什么呢?数据现象到底是高电平还是低电平?
这里就要体现出I2C总线硬件设计的精髓之处了
1、首先单片机IO口内部一般有两个mos管
所以当两个芯片的IO同时接在一个线上时,一端输出高电平,一端输出低电平,就会出现下面的情况:VCC和GND出现短路
2、I2C芯片做了阉割,去掉了上面的MOS管,所以这个时候不可能输出高电平,就不会出现短路的情况
但是相对的无法输出高电平了,所以加入了上拉电阻
这个时候由于上拉电阻的存在,总线就会处在高电平的状态,这也是为什么低电平是I2C的唤醒电平了
当芯片的io打开了mos管就会输出低电平,mos管关闭回到高电平
典型的GPIO开漏输出
这时候不会出现短路的现象了
上拉电阻的取值(在I2C电路中非常重要的问题)
此电阻不能太大也不能太小,一般就是几千欧姆
比较常用的是4.7KΩ
如果这个上拉电阻比较小,比如100Ω,当IO导通时,也就是电路为低电平时,整个的电流为33mA,容易损坏电路
当这个上拉电阻过大时:
1、首先每一个设备的IO口对地总是会有一些寄生电容
2、从低电平往高电平转换的过程中,也就是MOS管关断时,会先通过电流对这个电容充电,这导致I2C信号在变为高电平时会有一个爬坡的过程,也就是说,由于电容充电的过程,导致了信号从低到高转变的时间变慢,不是瞬间完成的
电阻越大,给电容充电的时间也就越慢,低电平变为高电平的转换也就越慢,
所以当总线上设备变多的时候,会适当减小上拉电阻值
一般选4.7K
所以由于上拉电阻的存在,以及寄生电容的存在,导致了高低电平转换的时间出现了快慢,也就导致了I2C的频率注定不高,另外就是抗干扰能力很弱
1、什么是总线协议
都用过串口协议,串口协议传输的成员只有两个,也就是协议传输的双方,但是如果有第三个也需要传输数据呢?增加一个串口?但是100个呢?
这就需要引入总线协议:也就是在总线上的多个设备之间可以传输信息
2、I2C总线
首先和串口线对比,串口线中有rx和tx,所以可以同时进行发送和接收
串口有波特率,为什么定义波特率呢?
假设现在将波特率设置为1,也就是1秒钟传输一个比特,发送方在1秒内发送一个bit,接收方在一秒内接受1bit,比如发送方一秒内发送了一个高电平,接收方就会接受一个高电平
但是如果波特率不同或者说混乱没有协商波特率的情况下:
发送方设置波特率为1,接收方设置波特率为2
发送方在一秒钟内发送了1bit,比如高电平,接收方却在一秒内接收了2次高电平
如果是9600和115200呢,是不是传输就混乱了?或者换句话说,没有波特率,大家互相之间就会胡乱传递
所以波特率其实就是互相之间进行了时统
有了这个概念再来理解I2C为什么存在时钟线了
I2C协议有SCL时钟线和SDA数据线
1、空闲状态:scl和sda都为高电平
2、起始信号:SCL为高电平,SDA从高到低,主机发起,其实就是为了告诉从机你们要准备接收数据了
也就是空闲时两根线都是高电平,当SDA跳变到低电平时就是起始信号
3、七位设备地址码:因为I2C总线上有很多设备,所以主机先发送想要访问的设备地址,该地址的设备就会明白主机将要和我进行通信了
4、发送数据时的逻辑1和逻辑0,可以看到当SCL为高电平时,此时看SDA数据线上的电平,为高就是逻辑1,为低就是逻辑0
也就是时钟线为高电平,数据线才有效,这就能看出来了时钟线的作用了,也就是双方进行了时统,这就对应上了串口在没有时钟线时做了波特率
5、读写数据位和应答信号
写数据:0 读数据:1
应答信号位:由从机发出
6、停止信号