原创 【学习笔记】IIC总线规范

2011-8-1 19:36 8619 5 5 分类: MCU/ 嵌入式

      
主要特性


l        串行总线:一条串行数据线SDA、一条串行时钟线SCL;


l        每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机;


l        真正的多主机总线:如果两个或更多主机同时初始化数据传输可以通过冲突检测和仲裁防止数据被破坏串行的8 位双向数据传输位速率在标准模式下可达100kbit/;快速模式下可达 400kbit/s 高速模式下可达
3.4Mbit/s;


l        片上的滤波器可以滤去总线数据线上的毛刺波保证数据完整;


l        连接到相同总线的 IC 数量只受到总线的最大电容 400pF 限制。


主要术语


   主机初始化总线的数据传输并产生允许传输的时钟信号的器件;从机是任何被寻址的器件。主机控制整个通信,可随时发起或结束通信;而从机只能被动的响应通信。


  发送器在一次通信过程中发送数据到总线的器件;接受器在一次通信过程中从总线上接受数据的器件。主机和从机通信时均可作为发送器或接受器。发送器产生数据,接受器接受数据。发送器和接受器的关系是动态变化的,同一器件(主机或从机)某一时刻可作为发送器,也可在另一时刻作为接受器。由当时数据传输的方向而定。


  多主机即同一总线上可连接多个主机进行通信,但某一时刻只允许一个主机控制总线。仲裁指多个主机同时尝试控制总线,由某种机制判定哪个主机获得总线控制权。这是多主机共享总线通信时必须面临的问题。

a1a2daa5-957b-4eb0-a971-981be9f5f43c.JPG

总线协议


SCL、SDA信号变化


  SDA和SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压。当总线空闲时,这两条线路都是高电平,连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能


  SCL主要由主机控制,从机仅在从机忙时拉低SCL通知主机“忙”。


  SDA在起始和结束条件时由主机控制,发送字节数据时由发送器控制,发送响应位时由接收器控制。


1.   起始/结束条件


起始条件:由主机产生,在SCL为高时,产生一个下跳沿。


结束条件:由主机产生,在SCL为高时,产生一个上跳沿。


584d9d5b-90fc-4091-98b0-92629bdc0b20.JPG

程序清单  .1 起始条件产生

void I2CStart ()


{


   SDA_HIGH();                                                  


    Delay(2);


    SCL_HIGH();


    Delay(2);


 


    // SCL为高,SDA从高到低,产生起始条件


SDA_LOW();                                /* 产生下降沿,产生起始条件 */


Delay(2);


   
SCL_LOW();                                    


    Delay(2);


}


程序清单 1.2 结束条件产生


void I2CStop ()


{


    SDA_LOW();


    Delay(1);


    SCL_HIGH();


    Delay(1);


         // IIC忙检测,主机释放SCL,如果此时SCL扔为低,则说明是被从机拉低


       while (SCL_STATUS() == 0) {


           // 在此加入超时功能。SM59R0XA2 -- 超时时间250ms


       }


 


    // SCL为高时,SDA由低变为高,产生停止条件


    SDA_HIGH();


    Delay(1);


}


2.   数据更新

  SCL为低时,更新数据;SCL为高时,采样数据。

0532bb95-2068-44f9-a762-77723d82f8a4.JPG

3.   字节格式

  每次发送8位数据,字节后紧跟响应位,先传MSB。响应位由接收器产生。从总线上接收数据的一方必须拉低SDA以响应(ACK)发送器。

n        当从机作为接收器时,若从机不能接收更多数据,则发送NACK给通知主机停止发送数据。即通知忙。

n        当主机作为接收器读从机数据时,在读取最后一个字节数据后发送NACK给从机,通知从机结束数据发送,释放SDA。

程序清单 1.3 主机写代码

INT8U  I2CSendByte (INT8U c)

{

    INT8U BitCnt;

    INT8U ack;

    Delay(2);

   SCL_LOW();


for (BitCnt=0;BitCnt<8;BitCnt++) {

    // 按字节发送数据,MSB先发送

        if( (c<< BitCnt) & 0x80) {

          SDA_HIGH();                               /* 低电平更改数据        */

      } else {

           SDA_LOW();

        }        
Delay(2);

     SCL_HIGH();                                                                /* 高电平告知从机接收数据 */


       
Delay(2);

        SCL_LOW();

    }

    // 释放SDA,释放SCL,接收应答位

    SDA_HIGH();

    Delay(2);

    SCL_HIGH();

    Delay(2);

    // 读取应答位

   if(SDA_STATUS() == I2C_ACK)

        ack = I2C_ACK;    

    else

        ack = I2C_NACK;    


    SCL_LOW();

    return ack;

}


程序清单 1.3 主机读代码

INT8U  I2CRcvByte()

{

    INT8U retc;

    INT8U BitCnt

   Delay(2);


    retc=0;  
SDA_HIGH();                                                /*置数据线为输入方式*/   
for(BitCnt=0;BitCnt<8;BitCnt++) {


        Delay(2);               // 拉低以允许数据线的改变       
SCL_LOW();                                      /*置时钟线为低,准备接收数据位*/       
Delay(2);


      SCL_HIGH();                              
  /*置时钟线为高使数据线上数据有效*/  
Delay(2);

        // 采样数据

        retc =retc << 1;


       if(SDA_STATUS())


           retc=retc+1;                                /*读数据位,接收的数据位放入retc中 */

       Delay(2);

    }


   SCL_LOW();   


    Delay(2) 
return(retc);

}


程序清单 1.3 主机发ACK/NACK代码


void I2CAck (INT8U a)

{

    Delay(2);

if (a==I2C_ACK) {


    SDA_LOW();                         /*在此发出应答或非应答信号 */


    } else {     
SDA_HIGH();

    }


    Delay(2);   

    SCL_HIGH();


    Delay(2);

   
SCL_LOW();                              /*清时钟线,钳住I2C总线以便继续接收*/


    Delay(2);


}


  如果从机需要时间完成某些功能(如处理接收到的数据或执行一些操作),可在接收和响应一个字节后,使时钟线SCL保持低电平迫使主机进入等待状态,直至从机准备好接收下一字节数据。相当于实现了主机和从机之间的“同步机制”,避免发送数据过快。

  如上所述,IIC中的“忙检测”有两种:

n        从机向主机发送NACK指示不要继续发送数据;


n        从机拉低SCK通知主机,从机正忙;

19b73153-acb8-4ecc-9311-790c5ac80a55.JPG
u            仲裁机制

  如果两个或多个主机尝试发送信息到总线,在其他主机都产生0的情况下首先产生一个 1 的主机将丢失仲裁。仲裁时的时钟信号是用线与连接到SCL 线的主机产生的时钟的同步结合。

  仲裁可以持续多位它的第一个阶段是比较地址位有关的寻址信息。如果每个主机都尝试寻址相同的器件。仲裁会继续比较数据位。如果是主机发送器或者比较响应位。如果是主机接收器,因为I2C总线的地址和数据信息由赢得仲裁的主机决定,在仲裁过程中不会丢失信息

u            标准IIC模式

4.   7位地址格式

  从机地址由一个固定和一个可编程的部分构成。可编程部分可能由它可使用的管脚决定,该部分地址决定了总线上可挂载的相同器件的数量。

     R/W指示读写,为1表示主机读从机,为0时,表示主机写从机。


7aac5b51-e4d4-4475-8e1b-f35582e83d57.JPG

  I2C 总线委员会协调I2C地址的分配进一步的信息可以从最后列出的Philips代理商处获得保留的两组8位地址 0000XXX和1111XXX的用途见表。


从机地址



R/W





0000000



0



广播呼叫地址



0000000



1



起始字节1



0000001X



CBUS



地址2



0000010



X



保留给不同总线格式



0000011



X



保留到将来使用



00001XX



X



Hs模式主机码



11111XX



X



保留到将来使用



11110XX



X



10位从机寻址




5.   7位地址传输模式

  7位地址传输模式如下,从机地址决定主机选择要操作的从机。R/W位决定了报文的方向,是读或者写。0表示主机向从机写,1表示主机读从机。此模式下,速度达100KBit/s。

  主机发送P终止当前通信;也可发送Sr和重复通信或寻址另一从机继续通信过程。这样就有多种不同的灵活的读写格式。不仅仅是以下几种。

8311c602-d66d-4d90-b266-66d6ae43e6d7.JPG

可能的格式有:

l        主机连续的写从机,从机产生ACk:

dbce90e4-d5cc-44a7-82bd-dc869396c1ae.JPG

l        主机连续的读从机,主机产生ACK和NACK(指示最后一个数据传输):

061d400f-4e2c-4fa1-af4a-dfbd9de00c5a.JPG


l        主机改变数据的传输方向,通过发送Sr和重复的从机地址。注意,此时可寻址其它主机通信

0a45a1f3-7e21-4559-9907-ab07a9e4a42c.JPG

          
快速IIC模式

扩展I2C总线规范主要有两个原因:

l        需提高IIC的位速度;由原来的100Kbit/s,提高至400KBit/s、3.4MBit/s;


l        扩展地址位数10位,以增加可寻址的器件数;


    IIC上下拉电阻问题


  下降沿的斜率由Miller电容C1和电阻R1 控制;上升时间tr主要由总线的电容负载和上拉电阻的值决定,阻值越大,上升时间越长!

4a9cde6e-f84f-4661-9d99-cc9b25f6dca3.JPG


  RP不宜过小,一般不低于1KΩ:电源电压限制了电阻Rp的最小值。一般 IO 端口的驱动能力在2mA~4mA量级。如果RP阻值过小,VDD灌入端口的电流将较大,这导致端口输出的低电平值增大(I2C协议规定,端口输出低电平的最高允许值为0.4V);如果灌入端口的电流过大,还可能损坏端口。故通常上拉电阻应选取不低于1KΩ的电阻(当VDD=3V时,灌入电流不超过 3mA)。


  RP不宜过大,一般不高于10KΩOD连接方式,信号由低电平变为高电闰时,是通过上拉电自动拉高实现,电源通过RP对线上负载电容CL充电,这需要一定的时间,即上升时间。IIC总线规范对上升时间有最大值要求。端口信号的上升时间可近似用充电时间常数RPCL乘积表示。如果RC充电时间常数过大,将使得信号上升沿变化缓慢,达不到数据传输的要求。信号线负载电容CL(对地)由多方面组成,包括器件引脚、PCB信号线、连接器等。如果信号线上挂有多个器件,负载电容也会增大。这也限制了总线上的器件数量。比如总线规定,对于的400kbps速率应用,信号上升时间应小于300ns;假设线上CL为20PF,可计算出对应的RP值为15KΩ。因此一般应用中选取的都是几KΩ量级的上拉电阻,比如都选取4K7的电阻。但是如果通过I/O口驱动使之输出高电低平,则上升时间不受限制。


    I2C协议还定义了串联在SDA、SCL线上电阻Rs。该电阻的作用是,有效抑制总线上的干扰脉冲进入从设备,提高可靠性。这个电阻的选择一般在100~200ohm左右。当然,这个电阻并不是必须的,在恶劣噪声环境中,可以选用。

      注意!在使用器件的GPIO内部上拉电阻时,有些MCU的上拉电阻阻值较大,并不适用于IIC总线,因此需要外接阻值较小上拉电阻,而不能因为GPIO内部有上拉电阻而使用该电阻。


n     PCB布线与抗干扰

   上 拉电阻应安置在OD输出端附近。当I2C总线上主从器件(Master & Slave)两端均为OD输出时,电阻放置在信号路径的中间位置。当主设备端是软件模拟时序,而从设备是OD输出时,应将电阻安置在靠近从设备的位置。


 

文章评论0条评论)

登录后参与讨论
相关推荐阅读
lstzixing 2014-01-20 07:28
与TKScope仿真器同行(1) - 看门狗会让你无法调试
  前几日,中矿龙科的李工向我反映了一个有意思的问题: 在使用TKScope仿真器(型号AK100pro)调试STM32时,出现了一个非常奇怪的现像。在Keil环境中的源代码设置了一...
lstzixing 2013-02-27 13:41
ARM指令仿真项目经历纪录一
这两天接了个新项目-ARM指令仿真项目,开发时间预期在两个月左右。这次将继承沿续自己以前做Cortex-A8、A9内核仿真项目时的方法,用日志纪录在开发过程中的各种问题解决方案和体会。限于某些原因...
lstzixing 2013-02-27 13:39
电子工程师应尝试产品经理的角色
做技术两三年了,发现自己一直陷入到技术细节当中,而从来没有尝试跳出来去从整个产品的角度进行观察。这其中可能是因为需要了解的技术细节太多,没有闲暇去关注技术之外的东西。另一方面也与个人的视野不够开阔...
lstzixing 2011-11-13 20:05
EDNChina的博客已经改得面目全面了
 之前有些日子没去ENDChina了。从08年起,断断续续地在这上面写一些技术类的Blog,到现在已经有快4年,虽然文章写的不多,但挺有感情的。   这两天回去看看,访问http://blog...
lstzixing 2011-10-14 22:02
TKScope仿真器使用入门视频教程
  相对来说,看视频肯定要比看PDF文档要容易的多吧。部门之前仅在网上发布了TKScope仿真器使用的PDF文档。虽然文档写的很详细,但实际真正愿意去看的不多。前些日子自己录制了TKScope仿真AR...
lstzixing 2011-09-18 23:00
尝试建立一个部门内部的知识库站点
前些天有事直接去找了下戚工反映TKScope仿真器方面的几个问题。问题解决之后闲聊了几句,其中就提及了建立一个共享的内部网络站点。当时我听了很兴奋,因为这个想法与我的不谋而合。早在刚进入这个部门不久,...
我要评论
0
5
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /3 下一条