I2C总线简介

I2C总线简介

1.  I2C总线是Philips公司提出的串行总线,但现在实际上已成为一个国际标准,在超过100种不同的IC上实现并得到超过50家公司的许可。它只用两根总线(时钟线SCL和数据线SDA)实现了多主的总线连接。它有3种模式:标准模式(100Kbits/s),快速模式(400Kbits/s)和高速模式(3.4Mbits/s),寻址方式有7位和10位方式。

2.  SCLSDA都是双向线路,都通过一个上拉电阻连接到正的电源电压,当总线空闲时这两条线路都是高电平。

 

3.  完整的I2C数据传输如下:

 

它包括起始条件、地址传送、数据传送、响应位、停止条件组成。起始条件是指在SCL线是高电平时,SDA从高电平向低电平切换。停止条件是指当SCL是高电平时,SDA从电平向高电平切换。接下来的一个字节包含7位地址和一位读/写控制位。接下来是主发到从或从发到主的数据,紧跟着的是响应位,由接收数据的设备发出。最后是停止位表示数据传输的完成。整个过程中传输的10是在SCL为高时SDA的电平决定的。而SDA线的高或低电平状态只有在SCL为低电平时才能改变。

4.  三种典型的数据传输模式。

A.       主机只发送数据给从机指定地址。

B.       主机寻址从机,只从从机读取数据。

C.       以上两种的复合模式,即主机既想向从机写数据又需要从机反馈数据。

 

 

 

/********************************************************************/

void StartIIC()                                   /*发送IIC总线启动时序*/

{

    SCL=1;

IICClockDelay();

SDA=1;

IICClockDelay();

    SDA=0;

IICClockDelay();

SCL=0;//在scl=0时可以改变sda状态

IICClockDelay();  

}

/********************************************************************/

void StopIIC()                                  /*发送IIC总线停止时序*/

{

    SDA=0;

IICClockDelay();

SCL=1;

IICClockDelay();

SDA=1;

IICClockDelay();

SCL=1;

IICClockDelay();

}

/********************************************************************/

/********************************************************************/

void IICClockDelay()                         /*IIC总线时钟电平延时*/

{

    nop;nop;nop;nop;nop;nop;

}

/********************************************************************/

void IICAck(bit ackValue)                /*应答/不应答函数,注意看谁对谁*/

{

if(ackValue==0)                                 

SDA=0;              

    else                                                

       SDA=1;

    IICClockDelay();

    SCL=1;

    IICClockDelay();

    SCL=0;

    IICClockDelay();

}

/********************************************************************/

 

 

 

bit IICSendByte(uchar byteData)          /*24C02发送一个字节数据或地址函数*/

{                                                             /*返回值为发送成功与否标志*/

    bit ackFlag;

    for(i=0;i<8;i++)                                 /*要传送的数据长度为8*/

    {

        if((byteData<<i)&0x80)                /*依次判断待发送位高低*/

            SDA=1;               

        else 

            SDA=0;                  

        IICClockDelay();

        SCL=1;                                   /*置时钟线为高,通知24C02开始接收数据位*/

        IICClockDelay();        

        SCL=0;

IICClockDelay();

    }

    SDA=1;                                /*8位数据发送完后释放数据线,准备接收应答位*/

    IICClockDelay();  

    SCL=1;

    IICClockDelay();

    if(SDA==1)

        ackFlag=0;                       /*24c02无应答*/    

    else

        ackFlag=1;                       /*数据成功发送*/

    SCL=0;

    IICClockDelay();

return(ackFlag);                   /*返回24C02应答标志*/

}

/********************************************************************/

uchar  IICRcvByte()    /*24C02读一个字节数据函数, 返回值为读入的该字节*/

{

    uchar retbyteData=0x00;              /*置返回值初值为0x00*/

    for(i=0;i<8;i++)

    {

        SDA=1;

        IICClockDelay();

        SCL=1;                                     /*拉高时钟线后读取数据线电平*/

        IICClockDelay();

retbyteData=retbyteData<<1;   /*返回值依次左移一位*/

if(SDA==1)                               /*读取数据线电平至于返回值空出的一位*/

{

retbyteData+=1;

}

SCL=0;                                      /*拉低释放时钟线*/     

IICClockDelay();

   }

   return(retbyteData);

}

/********************************************************************/

/*24C02的指定地址写入若干个数据函数*/

bit IICWrite(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num)

{

    bit retBit;      

    StartIIC();                                            /*启动总线*/

    retBit=IICSendByte(slaveAddress);            /*发送器件地址*/

    if(retBit==0)

        return(0);

    retBit=IICSendByte(subAddress);               /*发送器件子地址*/

    if(retBit==0)

        return(0);

    for(i=0;i<num;i++)

    {

        retBit=IICSendByte(*(dataPointer+i));    /*发送数据*/

        if(retBit==0)

            return(0);

    }  

    StopIIC();                                             /*结束总线*/

    return(0);

}

/********************************************************************/

/*24C02的指定地址读入若干个数据函数*/

bit IICRead(uchar slaveAddress,uchar subAddress,uchar *dataPointer,uchar num)

{

    bit retBit;   

    StartIIC();                                                  /*启动总线*/

    retBit=IICSendByte(slaveAddress);         /*发送器件从地址*/  

    if(retBit==0)

        return(0);  

    retBit=IICSendByte(subAddress);            /*发送器件子地址*/  

    if(retBit==0)

        return(0);

    StopIIC();                                                  /*结束总线*/

    StartIIC();                                           /*重新启动总线*/

    retBit=IICSendByte(slaveAddress+1);  

    if(retBit==0)

        return(0); 

    for(i=0;i<num-1;i++)

    {

        *dataPointer=IICRcvByte();                 /*接收数据*/

        IICAck(0);                                             /*发送应答位,mcu对24c02的应答*/

        dataPointer++;

    }                  

    *dataPointer=IICRcvByte();                     /*接收数据*/

    IICAck(1);//非应答,结束读操作的要求

    StopIIC();                                                  /*结束总线*/

    return(1);

}

/********************************************************************/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yantaoliu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值