|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
I2C协议
& b4 p, c5 x2 H( m1 A: ]: C6 P! `+ n' l0 |
I2C协议把传输的消息分为两种类型的帧: , m8 S$ o7 E7 W4 A" W# Z+ u
一个地址帧 —— 用于master指明消息发往哪个slave;
0 l1 B% M4 @ n( m/ ^% l9 m一个或多个数据帧 —— 由master发往slave的数据(或由slave发往master),每一帧是8-bit的数据。
" B- ]' `9 [$ I! }4 J注:协议要求每次放到SDA上的字节长度必须为8位,并且每个字节后须跟一个ACK位,在下面会讲到。
" G$ q( P# d/ x4 {0 [数据在SCL处于低电平时放到SDA上,并在SCL变为高电平后进行采样。读写数据和SCL上升沿之间的时间间隔是由总线上的设备自己定义的,不同芯片可能有差异。
$ _0 V. S( ?" }& K1 kI2C数据传输的时序图如下:
7 H. o- S! I+ \. x( c, c$ N) k2 ]9 z7 P7 `! J
开始条件(start condition):
% G! E8 E( T9 ?# o为了标识传输正式启动,master设备会将SCL置为高电平(当总线空闲时,SDA和SCL都处于高电平状态),然后将SDA拉低,这样,所有slave设备就会知道传输即将开始。如果两个master设备在同一时刻都希望获得总线的所有权,那么谁先将SDA拉低,谁就赢得了总线的控制权。在整个通信期间,可以存在多个start来开启每一次新的通信序列(communication sequence),而无需先放弃总线的控制权,后面会讲到这种机制。 - n9 P! \' `7 i, T3 `# S" s7 F! I
地址帧(address frame):
& l8 A$ B* ?% r% n% b! Q+ ?' P; N地址帧总是在一次通信的最开始出现。一个7-bit的地址是从最高位(MSB)开始发送的,这个地址后面会紧跟1-bit的操作符,1表示读操作,0表示写操作。
1 Y" C$ X) R1 I; Q接下来的一个bit是NACK/ACK,当这个帧中前面8bits发送完后,接收端的设备获得SDA控制权,此时接收设备应该在第9个时钟脉冲之前回复一个ACK(将SDA拉低)以表示接收正常,如果接收设备没有将SDA拉低,则说明接收设备可能没有收到数据(如寻址的设备不存在或设备忙)或无法解析收到的消息,如果是这样,则由master来决定如何处理(stop或repeated start condition)。
, ]* _' C2 I/ p! F9 a1 N数据帧(data frames): ( }+ c. l4 F7 w2 f
在地址帧发送之后,就可以开始传输数据了。Master继续产生时钟脉冲,而数据则由master(写操作)或slave(读操作)放到SDA上。每个数据帧8bits,数据帧的数量可以是任意的,直到产生停止条件。每一帧数据传输(即每8-bit)之后,接收方就需要回复一个ACK或NACK(写数据时由slave发送ACK,读数据时由master发送ACK。当master知道自己读完最后一个byte数据时,可发送NACK然后接stop condition)。 1 W5 f4 B' M' _8 C' u
停止条件(stop condition):
3 @% J' _* f# q5 s当所有数据都发送完成时,master将产生一个停止条件。停止条件定义为:在SDA置于低电平时,将SCL拉高并保持高电平,然后将SDA拉高。 - z: z& |. F4 p* d) G
注意,在正常传输数据过程中,当SCL处于高电平时,SDA上的值不应该变化,防止意外产生一个停止条件。
- T1 e# F6 a" ?; d2 X9 t3 N1 O重复开始条件(repeated start condition): ! D: b" V7 P3 t: Q- H
有时master需要在一次通信中进行多次消息交换(例如与不同的slave传输消息,或切换读写操作),并且期间不希望被其他master干扰,这时可以使用“重复开始条件” —— 在一次通信中,master可以产生多次start condition,来完成多次消息交换,最后再产生一个stop condition结束整个通信过程。由于期间没有stop condition,因此master一直占用总线,其他master无法切入。
1 A* L6 |% F3 f3 @4 a7 ~; ^3 e2 s为了产生一个重复的开始条件,SDA在SCL低电平时拉高,然后SCL拉高。接着master就可以产生一个开始条件继续新的消息传输(按照正常的7-bit/10-bit地址传输时序)。重复开始条件的传输时序如下图所示: / `6 _: @- b! a) `& C
( b, _7 F% g4 m) |0 j时钟拉伸(clock stretching): $ Z" I; V& r- |( P4 P
有时候,低速slave可能由于上一个请求还没处理完,尚无法继续接收master的后续请求,即master的数据传输速率超过了slave的处理能力。这种情况下,slave可以进行时钟拉伸来要求master暂停传输数据 —— 通常时钟都是由master提供的,slave只是在SDA上放数据或读数据。而时钟拉伸则是slave在master释放SCL后,将SCL主动拉低并保持,此时要求master停止在SCL上产生脉冲以及在SDA上发送数据,直到slave释放SCL(SCL为高电平)。之后,master便可以继续正常的数据传输了。可见时钟拉伸实际上是利用了时钟同步的机制(见下文),只是时钟由slave产生。 " [7 ?( ~" X$ J
如果系统中存在这种低速slave并且slave实现了clock stretching,则master必须实现为能够处理这种情况,实际上大部分slave设备中不包含SCL驱动器的,因此无法拉伸时钟。
) @9 y5 v* v* T7 }. a所以更完整的I2C数据传输时序图为:
& i' T% t% ]/ M) U7 L( ~, t% C8 H
10-bit地址空间:
7 H3 g" N0 r! e上面讲到I2C支持10-bit的设备地址,此时的时序如下图所示:
% }! u" D8 I3 j7 [# R. j
4 \1 @6 Z$ Q) z; o' [6 C. U+ t在10-bit地址的I2C系统中,需要两个帧来传输slave的地址。第一个帧的前5个bit固定为b11110,后接slave地址的高2位,第8位仍然是R/W位,接着是一个ACK位,由于系统中可能有多个10-bit slave设备地址的高2bit相同,因此这个ACK可能由多有slave设备设置。第二个帧紧接着第一帧发送,包含slave地址的低8位(7:0),接着该地址的slave回复一个ACK(或NACK)。 + x& B0 u) {. Y6 P& k
注意,10-bit地址的设备和7-bit地址的设备在一个系统中是可以并存的,因为7-bit地址的高5位不可能是b11110。实际上对于7-bit的从设备地址,合法范围为b0001XXX-b1110XXX,’X’表示任意值,因此该类型地址最多有112个(其他为保留地址[1])。
/ g: n) x- y2 }) n( Z6 A两个地址帧传输完成后,就开始数据帧的传输了,这和7-bit地址中的数据帧传输过程相同。
; x% A0 t3 ?* k( Y; s: ?
) J$ Y2 B6 o' y1 y时钟同步和仲裁
0 L# E2 ~- `- q如果两个master都想在同一条空闲总线上传输,此时必须能够使用某种机制来选择将总线控制权交给哪个master,这是通过时钟同步和仲裁来完成的,而被迫让出控制权的master则需要等待总线空闲后再继续传输。在单一master的系统上无需实现时钟同步和仲裁。. r8 M9 E7 f ~6 s
/ g/ m" E+ H8 P4 m- \. b
时钟同步
& I9 Q+ s$ Q1 O时钟同步是通过I2C接口和SCL之间的线“与”(wired-AND)来完成的,即如果有多个master同时产生时钟,那么只有所有master都发送高电平时,SCL上才表现为高电平,否则SCL都表现为低电平。
3 k' w# _7 G, C. `5 P: ` G( D* k% Q3 @9 O
总线仲裁, f' E* k& L, V; L0 o/ h
总线仲裁和时钟同步类似,当所有master在SDA上都写1时,SDA的数据才是1,只要有一个master写0,那此时SDA上的数据就是0。一个master每发送一个bit数据,在SCL处于高电平时,就检查看SDA的电平是否和发送的数据一致,如果不一致,这个master便知道自己输掉仲裁,然后停止向SDA写数据。也就是说,如果master一直检查到总线上数据和自己发送的数据一致,则继续传输,这样在仲裁过程中就保证了赢得仲裁的master不会丢失数据。
" T0 e2 k5 X: v7 T) R. A8 r输掉仲裁的master在检测到自己输了之后也不再产生时钟脉冲,并且要在总线空闲时才能重新传输。
' J" Y& x |$ z. j( G H8 `仲裁的过程可能要经过多个bit的发送和检查,实际上两个master如果发送的时序和数据完全一样,则两个master都能正常完成整个的数据传输。$ m5 Z P, w% v$ l q. u/ ?
|
|