1. 初见IIC
小y最近比较闲暇,所以开始自学IIC原理。在U公司工作的时候只知道IIC是半双工,并且也知道是IIC协议是用于芯片之间得低速通信,速度分为100Kb/s、400Kb/s和3.4Mb/s。如果从物理上直接观看得话就是两根线,一根SDA数据线,一根SCL时钟线,其他的暂时不清楚。但是现在在H公司工作了,并且是研发岗位,那么我有义务搞清楚IIC得原理。所以y拿起了IIC的通信协议看了起来。毕竟在研发层面要知其然知其所以然。此篇文章目的是做一下总结。
下图是IIC一个最基础的一个电路图,如下图1所示
我们可以看到IIC的SDA和SCL两根线ARM和EEPROM是“挂”在这两根线上的,所以如果有一个芯片坏了并不会造成整个设备无法正常运行。
善于观察的人突然发现为毛在这两个个信号线上会有两个上拉电阻呢?
于是我翻看IIC的资料从版本2.0-1998得知SDA和SCL上的电压要求是2V。无意中还得知IIC原来是通过地址沟通的,有 7 位地址和 10 位地址寻址方式。
这里我就按7位去写吧,原理其实差不多。
将地址以从高到低写出
如上图2所示,D3芯片XXX是应为图1的EEPROM上有三个电阻,如果有上拉则1无上拉则为0。所以EEPROM有8个可以根据阻值改变的地址不被软件写死。
有的人会出现疑问了既然你是以7位地址为例那么为啥你的一个字节有9位?是不是画错了!
2. IIC波形图
当然不是,y在写这篇博客前经过深思熟虑的。那么我想问问大家如果芯片D1需要读取EEPROM的数据,那么应该怎么告诉EEPROM呢?如果闲的蛋疼工程师比如我,再我读取完数据非要给D2芯片ARM传输数据该怎么办呢?
当第一位是0的时候D1的ARM将发送数据到D2的ARM;
当第一位是1的时候D1的ARM将接受数据从到D3的EEPROM如下图3所示
为啥我没有画两个箭头就是因为我开篇说了IIC是半双工。
那么我将IIC传输模式总的分为4种模式。
- D1芯片发送数据到D2芯片
- D1芯片接受D3芯片数据
- D1芯片发送数据到D2芯片处理,D2返回处理的数据给D1
- D1和D2几乎同时发送数据到D3
个人觉得第一种最简单直接把数据发送到D2,只有一个流程,那么我们先分析第一个吧。
首先我们应该知道IIC何时开始通信何时结束,没头没尾的事咱不干。于是y
打开IIC的协议说明查看后得知SCL在高电平时,SDA降为低电平的时候为开始,并且偷偷的发现SCL在高电平时,SDA上升为高电平的时候为结束,那么开始的标记如下图所示。
此时是IIC的起始标记信息。
当SDA由低变高,且SCL保持高电平时,此时设备通信结束。所以总结下当SCL为高电平的时候SDA的改变只会改变开始与结束。
此时有好事者张三提出问题:那么当SDA在高SCL,或者SDA为低SCL也为低呢?
当SDL为低的时候IIC的其他设备开始采样SDA的数据,采样7位。
以D1发送数据到D2为例。
D2的地址时1010101那么D1发送的信号如下图所示。
上图已经显示出来D1芯片发送了10101010的地址,这个正好是D2芯片的地址,并且最后一个0意味着D1将要发送数据到D2。然而D1怎么知道D2是否收到了信息呢?
D2芯片会自动将第8位拉低到0,及101010100表示D1发送数据到D2,并且D2答复了。
那如果D2刚好坏了呢?
D2损坏后D1会一直保持高电平占用着SDA 总线,效果如下:
当D2应答后D1 便开始发送数据到D2,这里为了简便发送01001000B到D2上然后结束通信。
分析:SDA会发送:
1、地址是1010101,
2、写入数据是0,
3、应答位是0,
4、传输数据01001000,
5、应答接受一个字节完毕,应答位是0;
6、结束应答1
上图是完成的D1写入之D2,那么下图是D1接受D2的数据图:
那么D1芯片发送数据到D2芯片处理,D2返回处理的数据给D1该怎么办呢?难道是D1当完主机在D2当主机吗?这个是不被IIC容许的,如果在D1完成后别的芯片比D2快一点点向D2写数据那不就乱套了。
于是我经过分析得出如果改变数据位的第8位将0变成1那不就完美解决吗?
分析结果如下
1、D1发送地址是1010101,
2、D1发送写入数据是0,
3、D2发送应答位是0,
4、D1发送传输数据01001000,
5、D2发送应答接受一个字节完毕,应答位是0;
6、D1发送地址是1010101,
7、D1发送写入数据是1,
8、D2发送应答位是0,
9、D1发送传输数据01001000,
10、D2发送应答接受一个字节完毕,应答位是0;
11、结束应答1
得出时序图是这样的
由上图发现D1在完成数据传输后如果后续还有动作可以取消STOP,直接继续使用START。
我才发现飞利浦的老哥有点骚呀。
3. IIC仲裁
此时当D1、D2同时要读取D3的内容又或者D1读取D3的数据的同时D2给D1发送数据,那该怎么办呐?
如果小y是工程师那么这个时候需要有个裁判,来判断是谁先传输。这个时候发现飞利浦的老哥跟我想法一样,于是便有了仲裁机制。仲裁必须要有两个必要条件。
1、SCL同步
2、SDA仲裁
首先分析第一种情况
1、
SCL同步原理。
简单的称述就是当有器件拉低SCL的时候SCL立马呈现低电平。及1&1=1、1&0=0。
当D1、D2同时读取D3的数据,SDA同样和SDA1和SDA2具有&的协议及SDA&&SDA1=1参与竞争,否则退出竞争。
上图中SDA2率先开始发送数据但是它与总线的SDA做&&运算后结果为0,所以此时传输数据的应该时SD1。
最后一点需要注意的是快速模式才有仲裁。