IIC总线

一、 概述

  1. IIC总线是PHILIPS公司推出的一种串口总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串口总线。

  2. IIC总线只有两根双向信号线。一根是数据线SDA,一根是时钟线SCL。

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

  

  4. IIC总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任何一个器件输出的低电平,都将使总线的信号变低,

  即各器件的SDA和SCL都是线“与”的关系。

  

  5. 每个连到总线上的器件都有一个唯一的地址。主机与其他器件的数据传送可以使主机发送数据到其他器件,这时主机就是发送器。在总线上

  接受数据的器件则为接收器。

  6. 在多主机系统中,可能同时有几个主机企图启动总线发送数据,为了避免混乱,IIC总线要通过总线仲裁,以决定由哪一台主机控制总线。

 

二、 IIC总线的数据传送

  1. 数据位的有效性

  IIC总线在进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定;只有在时钟线上的信号是低电平时,数据线上的电平才允许变化。

  

 

  2. 起始和终止信号

  SCL线为高电平期间,SDA线由高到低变化表示起始。

  SCL线为高电平期间,SDA线由低到高变化表示终止。

  

  起始和终止都是主机发出的,在起始信号开始后,总线就处于被占用状态;在终止信号产生后,总线就处于空闲状态。

  连接到IIC总线上的设备,如果具有IIC总线的硬件接口,很容易检测到起始和终止信号。

  接收器收到一个完整的数据字节后,有可能需要完成一些其他工作,可能无法立刻接收下一个字节,这时接收器可以将SCL线拉低,

  从而使主机处于等待状态。直到slave device准备好接收下一个字节时,再释放SCL线使之为高电平,从而数据传输continue.

 

三、 数据传送格式

  1. 字节传送与应答

  每个字节必须是8bit长度。数据传送时,先传最高位MSB,每一个被传送字节后面必须跟一个应答位(即一帧共9个bit)。

  

  如果slave不对master做寻址信号应答时,slave必须将数据线SDA置于高电平,而由主机产生一个STOP信号以结束传送。

  如果slave对master寻址应答后,但在数据传送一段时间后无法继续接收更多数据时,slave可以对无法接收的第一个数据字节“非应答”

  通知主机。主机则发出STOP信号以结束数据传送。

  当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是对从机的“非应答”来实现的。然后,

  从机释放SDA线,允许主机产生STOP信号。

 

  2. 数据帧格式

  IIC总线上传送的数据信号是广义的。既包括地址信号,也包含真正的数据信号。

  在起始信号后必须传送一个从机的地址(7bit),第8位是数据的传送方向位(R/T)。“0”表示主机发送数据(T/write),“1”表示主机

  接收数据(R/Read)。每次数据传送总是由主机产生终止信号。

  但是,如果主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一个从机进行寻址。

   在总线的一次数据传送中,可以有以下几种组合方式:

  (阴影部分表示数据从主机向从机传送,无阴影部分表示数据由从机向主机传送。A表示应答,A非表示非应答(高电平)。S是起始信号,P表示终止信号。)

  1)主机向从机发送数据,数据传送方向在整个传送过程中不变:

  

  2)主机在第一个字节后,立即从从机读数据。

  

  3)在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读写方向位正好反相。

  

 

四、IIC总线的寻址

  IIC总线有明确规定:采用7bit寻址字节(寻址字节是起始信号后的第一个字节)。

  

  D7~D1位组成从机的地址。D0位是数据传送方向位。"0"表示主机向从机写数据,"1"表示主机向从机读数据。

  主机发送地址时,总线上的每个从机都将这7位地址码和自己的地址比较,如果相同,则认为自己被主机寻址,根据R/T位将自己确认为发送器

  或者接收器。

  从机的地址由固定部分和可编程部分组成。在一个系统中,可能希望接入多个相同的从机,从机地址中可以编程的部分决定了可接入总线该类器件

  的最大数目。

 

 

  (基本的I2C总线规范于20年前发布,其数据传输速率最高为100Kbits/s,采用7位寻址。但是由于数据传输速率和应用功能的迅速增加,I2C总线

  也增强为快速模式(400Kbits/s)和10位寻址以满足更高速度和更大寻址空间的需求。

  I2C总线始终和先进技术保持同步,但仍然保持其向下兼容性。并且最近还增加了高速模式,其速度可达3.4Mbits/s。它使得I2C总线能够支持现有

  以及将来的高速串行传输应用,例如EEPROM和Flash存储器。)

 

 

参考来源:红茶的博客->IIC总线  http://blog.sina.com.cn/s/blog_9815359e01012c6k.html

 

 

 

 

附:模拟IIC代码

 

/**************************************************************
 * 函数名:IIC_Start
 * 描  述:产生起始信号
 * 说  明:SCL为高电平时,SDA下降沿启动信号
**************************************************************/
void IIC_Start(void)
{
    IIC_SDA_OUT();        // SDA线设置为输出
    IIC_SDA_SET();        // SDA线输出高电平
    delay_us(5);
    IIC_SCL_SET();        // SCL线输出高电平
    delay_us(5);
    IIC_SDA_CLR();        // SDA线产生下降沿 
    delay_us(5);  
  IIC_SCL_CLR();        // 钳住I2C总线,准备发送或接收数据
}

 

/**************************************************************
 * 函数名:IIC_Stop
 * 描  述:产生停止信号
 * 说  明:SCL为高电平时,SDA一个上升沿停止信号
**************************************************************/
void IIC_Stop(void)
{
    IIC_SDA_OUT();            // SDA线设置为输出
    IIC_SCL_CLR();            // SCL线输出低电平
    delay_us(5);
    IIC_SDA_CLR();            // SDA线输出低电平
    delay_us(5);
    IIC_SCL_SET();            // SCL线输出高电平
    delay_us(5);
  IIC_SDA_SET();            // SDA线输出高电平
    delay_us(5);
}

 

/**************************************************************
 * 函数名:IIC_Wait_Ack
 * 描  述:等待接收应答信号
 * 说  明:每传送一个字节的数据(地址及命令)后,接收设备都会产生
        一个应答信号。SCL为高电平期间,接受设备将SDA拉低表示应答,
        否则为非应答
 * 返回值:1,接收应答失败        0,接收应答成功
**************************************************************/
unsigned char IIC_Wait_Ack(void)
{
    unsigned char ucErrTime=0;
    IIC_SDA_SET();
    IIC_SDA_IN();
    IIC_SCL_SET();
    while(READ_SDA())
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            IIC_Stop();
            return 1;
        }
    }
        IIC_SCL_CLR();
        return 0;
}

 

/**************************************************************
 * 函数名:IIC_Ack or IIC_NACK
 * 描  述:产生应答信号
 * 说  明:SCL为高电平期间,SDA为低电平表示应答,否则为非应答
**************************************************************/
// 应答
void IIC_Ack(void)
{
    IIC_SCL_CLR();            // SCL线输出低电平
    IIC_SDA_OUT();            // SDA线设置为输出
    IIC_SDA_CLR();            // SDA线输出低电平
    delay_us(5);
    IIC_SCL_SET();            // SCL线输出高电平
    delay_us(5);
    IIC_SCL_CLR();            // SCL线输出低电平
}
// 非应答
void IIC_NACK(void)
{
    IIC_SCL_CLR();            // SCL线输出低电平
    IIC_SDA_OUT();            // SDA线设置为输出
    IIC_SDA_SET();            // SDA线输出高电平
    delay_us(5);
    IIC_SCL_SET();            // SCL线输出高电平
    delay_us(5);
    IIC_SCL_CLR();            // SCL线输出低电平
}

 

/**************************************************************
 * 函数名:IIC_Send_Byte
 * 描  述:发送一个字节的数据(地址或命令)
 * 输  入:txd,需要发送的数据
 * 说  明:IIC总线进行数据传输时,SCL为高电平期间SDA上的数据必须
                     保持稳定,只有SCL为低电平期间SDA上的数据才允许变化。
                     数据传送时,先传高位后传低位。
**************************************************************/
void IIC_Send_Byte(unsigned char txd)
{
    signed char t;
    IIC_SDA_OUT();
    IIC_SCL_CLR();            // 拉低时钟线SCL,开始数据传输
    for(t=7; t>=0; t--)
    {
        if( 0 != (txd & (1 << t)) )            // 如果data的第i位不为0
        {
            IIC_SDA_SET();            // SDA线输出高电平
        }
        else
        {
            IIC_SDA_CLR();            // 否则SDA线输出低电平
        }
        delay_us(5);
        IIC_SCL_SET();
        delay_us(5);
        IIC_SCL_CLR();
        delay_us(5);
    }
    IIC_Wait_Ack();    
}

 

/**************************************************************
 * 函数名:IIC_Read_Byte
 * 描  述:接收一个字节的数据(地址或命令)
 * 输  入:rxd,在IIC总线上读取的数据
 * 说  明:IIC总线进行数据传输时,SCL为高电平期间数据才是稳定的,
                     所以在SCL高的时候读取SDA上的数据。
**************************************************************/
unsigned char IIC_Read_Byte(unsigned char ack)
{
    unsigned char i,rxd=0;
    IIC_SDA_IN();
    for( i=0;i<8;i++ )
    {
        
        IIC_SCL_CLR();
        delay_us(5);
        IIC_SCL_SET();
        delay_us(5);
        rxd<<=1;
        if(READ_SDA())    rxd++;
    }
    if(!ack)    IIC_NACK();
    else    IIC_Ack();
    return rxd;    
}

 

posted @ 2016-07-18 14:12  WillBeBetter  Views(2515)  Comments(0Edit  收藏  举报