精华内容
下载资源
问答
  • i2c时序图
    千次阅读
    2017-05-18 16:23:00


    开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
    结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
    应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,
    表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接
    收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为
    受控单元出现故障。


    支持不同的通讯速度
    ─  标准速度(高达100 kHz)
    ─  快速(高达400 kHz)

    更多相关内容
  • I2C时序图的详细讲解

    2018-03-26 19:32:42
    I2C时序图的详细讲解,简易时序图,经典I2C测试讲解。
  • i2c时序图的详细讲解

    万次阅读 多人点赞 2018-04-25 21:25:22
    i2c简易时序图 启动信号: SCL为高电平的时候,SDA由高电平向低电平跳变。结束信号:SCL为高电平的时候,SDA由低电平向高电平跳变。 应答信号: I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节...

     i2c简易时序图

      启动信号:

      SCL为高电平的时候,SDA由高电平向低电平跳变。结束信号:SCL为高电平的时候,SDA由低电平向高电平跳变。

      应答信号:

      I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功,对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

      写时序:

      开始信号:主机+从设备地址+写命令,从机应答,应答成功,表示有这个设备,然后主机+设备内部寄存器地址,此时不用再加写命令控制字,从机应答,应答成功,表示设备内有这个地址,主机写入数据,从机应答,是否继续发送,不发送的话,发送停止信号P。

      读时序:

      要想读设备,首先要知道将要所读取设备的地址告诉从设备,从设备才能将数据放到(发送)SDA上使主设备读取,从设备将数据放入SDA上的过程,由硬件主动完成,不用人为的写入。所以首先先写入从机地址,然后+写控制命令,从机应答,应答成功,表示有这个设备,然后写入内部寄存器地址,此时不用再加写命令控制字,从机应答,应答成功,表示设备内有这个地址。然后主机继续发出:写入从机地址,然后+读命令,从机应答,应答成功,此时便可以读取数据了,从设备已经将数据放入到SDA上了。地址跟设备已经验证了,不用再进行验证。

      启动信号与停止信号的时序图如下图所示:

    i2c时序图的详细讲解

      数据位发送:

      在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。进行数据传送时,在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。只有在SCL为低电平期间,才允许SDA上的电平改变状态。逻辑0的电平为低电压,而逻辑1则为高电平。时序如下图所示

    i2c时序图的详细讲解

      应答信号时序图如下图所示:

    i2c时序图的详细讲解

      当进行一次写时序的时候,SDA上的数据变化的时序图如下:

    i2c时序图的详细讲解

      当进行一次读的时候,SDA上的数据变化的时序图如下:

    i2c时序图的详细讲解

      i2c协议中的数据传输时序图如下:

    i2c时序图的详细讲解

      I2C总线信号时序总结

      总线空闲状态

      I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

    i2c时序图的详细讲解

      启动信号

      在时钟线SCL保持高电平期间,数据线SDA上的电平被拉低(即负跳变),定义为I2C总线总线的启动信号,它标志着一次数据传输的开始。启动信号是一种电平跳变时序信号,而不是一个电平信号。启动信号是由主控器主动建立的,在建立该信号之前I2C总线必须处于空闲状态。

      重启动信号

      在主控器控制总线期间完成了一次数据通信(发送或接收)之后,如果想继续占用总线再进行一次数据通信(发送或接收),而又不释放总线,就需要利用重启动Sr信号时序。重启动信号Sr既作为前一次数据传输的结束,又作为后一次数据传输的开始。利用重启动信号的优点是,在前后两次通信之间主控器不需要释放总线,这样就不会丢失总线的控制权,即不让其他主器件节点抢占总线。

      重启动信号

      在主控器控制总线期间完成了一次数据通信(发送或接收)之后,如果想继续占用总线再进行一次数据通信(发送或接收),而又不释放总线,就需要利用重启动Sr信号时序。重启动信号Sr既作为前一次数据传输的结束,又作为后一次数据传输的开始。利用重启动信号的优点是,在前后两次通信之间主控器不需要释放总线,这样就不会丢失总线的控制权,即不让其他主器件节点抢占总线。

      停止信号

      在时钟线SCL保持高电平期间,数据线SDA被释放,使得SDA返回高电平(即正跳变),称为I2C总线的停止信号,它标志着一次数据传输的终止。停止信号也是一种电平跳变时序信号,而不是一个电平信号,停止信号也是由主控器主动建立的,建立该信号之后,I2C总线将返回空闲状态。

      不是在数据有效性中规定在SDA只能在SCL的低电平的时候变化,为何STAR,STOP不一样?首先STAR和STOP不是数据,所以可以不遵守数据有效性中的规定,其它数据都遵守,而STAR和STOP“不遵守”导致STAR和STOP更容易被识别。这样不是不遵守而是更有优势。

      起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态,在停止条件的某段时间后总线被认为再次处于空闲状态。

      如果产生重复起始(Sr) 条件而不产生停止条件,总线会一直处于忙的状态。此时的起始条件(S)和重复起始(Sr) 条件在功能上是一样的。

      如果连接到总线的器件合并了必要的接口硬件,那么用它们检测起始和停止条件十分简便。但是没有这种接口的微控制器在每个时钟周期至少要采样SDA 线两次来判别有没有发生电平切换。

      i2c时序图的详细讲解

      数据位传送

      在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。进行数据传送时,在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。只有在SCL为低电平期间,才允许SDA上的电平改变状态。逻辑0的电平为低电压,而逻辑1的电平取决于器件本身的正电源电压VDD(当使用独立电源时)。数据位的传输是边沿触发。

      i2c时序图的详细讲解

      应答信号

      I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

      i2c时序图的详细讲解

      插入等待时间

      如果被控器需要延迟下一个数据字节开始传送的时间,则可以通过把时钟线SCL电平拉低并且保持,使主控器进入等待状态。一旦被控器释放时钟线,数据传输就得以继续下去,这样就使得被控器得到足够时间转移已经收到的数据字节,或者准备好即将发送的数据字节。带有CPU的被控器在对收到的地址字节做出应答之后,需要一定的时间去执行中断服务子程序,来分析或比较地址码,其间就把SCL线钳位在低电平上,直到处理妥当后才释放SCL线,进而使主控器继续后续数据字节的发送。

      i2c时序图的详细讲解

      总线封锁状态

      在特殊情况下,如果需要禁止所有发生在I2C总线上的通信活动,封锁或关闭总线是一种可行途径,只要挂接于该总线上的任意一个器件将时钟线SCL锁定在低电平上即可。

      总线竞争的仲裁

      总线上可能挂接有多个器件,有时会发生两个或多个主器件同时想占用总线的情况,这种情况叫做总线竞争。I2C总线具有多主控能力,可以对发生在SDA线上的总线竞争进行仲裁,其仲裁原则是这样的:当多个主器件同时想占用总线时,如果某个主器件发送高电平,而另一个主器件发送低电平,则发送电平与此时SDA总线电平不符的那个器件将自动关闭其输出级。总线竞争的仲裁是在两个层次上进行的。首先是地址位的比较,如果主器件寻址同一个从器件,则进入数据位的比较,从而确保了竞争仲裁的可靠性。由于是利用I2C总线上的信息进行仲裁,因此不会造成信息的丢失。

      为何识别到“0”将丢失仲裁呢?因为对于OD门,只能驱动到低电平,释放总线只能通过不驱动总线释放,停止驱动即产生“1”,但是发现总线还是“0”,这说明还有主机在跟自己竞争总线使用权,自己线驱动到“1”,确检测到“0”,那代表自己已经失去了仲裁。

      主机只能在总线空闲的时侯启动传送。两个或多个主机可能在起始条件的最小持续时间tHD;STA 内产生一个起始条件,结果在总线上产生一个规定的起始条件。

      当SCL 线是高电平时,仲裁在SDA 线发生;这样,在其他主机发送低电平时,发送高电平的主机将断开它的数据输出级,因为总线上的电平与它自己的电平不相同。然后,进一步获得其的判定条件:

      仲裁可以持续多位。首先是比较地址位。如果每个主机都试图寻址同一的器件,仲裁会继续比较数据位(假设主机是发送器),或者比较响应位(假设主机是接收器)。

      I2C 总线的地址和数据信息由赢得仲裁的主机决定,在仲裁过程中不会丢失信息。丢失仲裁的主机可以产生时钟脉冲直到丢失仲裁的该字节末尾。

      在串行传输过程中时,一旦有重复的起始条件或停止条件发送到I2C 总线的时侯,仲裁过程仍在进行。如果可能产生这样的情况,有关的主机必须在帧格式相同位置发送这个重复起始条件或停止条件。

      此外,如果主机也结合了从机功能,而且在寻址阶段丢失仲裁,它很可能就是赢得仲裁的主机在寻址的器件。那么,丢失仲裁的主机必须立即切换到它的从机模式。

      I2C 总线的控制只由地址或主机码以及竞争主机发送的数据决定,没有中央主机,总线也没有任何定制的优先权。

      i2c时序图的详细讲解

      上图显示了两个主机的仲裁过程当然可能包含更多的内容由连接到总线的主机数量决定此时产生DATA1 的主机的内部数据电平与SDA 线的实际电平有一些差别如果关断数据输出这就意味着总线连接了一个高输出电平这不会影响由赢得仲裁的主机初始化的数据传输。

      时钟信号的同步

      在I2C总线上传送信息时的时钟同步信号是由挂接在SCL线上的所有器件的逻辑“与”完成的。SCL线上由高电平到低电平的跳变将影响到这些器件,一旦某个器件的时钟信号下跳为低电平,将使SCL线一直保持低电平,使SCL线上的所有器件开始低电平期。此时,低电平周期短的器件的时钟由低至高的跳变并不能影响SCL线的状态,于是这些器件将进入高电平等待的状态。当所有器件的时钟信号都上跳为高电平时,低电平期结束,SCL线被释放返回高电平,即所有的器件都同时开始它们的高电平期。其后,第一个结束高电平期的器件又将SCL线拉成低电平。这样就在SCL线上产生一个同步时钟。可见,时钟低电平时间由时钟低电平期最长的器件确定,而时钟高电平时间由时钟高电平期最短的器件确定。

      i2c时序图的详细讲解

    展开全文
  • I2C协议---I2C时序图解析

    万次阅读 多人点赞 2018-08-08 19:55:57
    一、I2C协议简介   I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚...  关于I2C协议的更多内容,可阅读《I2C总线协议》,本博文主要分析I2C波形,对于I2C的基础知识不在做介...

     

    一、I2C协议简介

      I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地 使用在系统内多个集成电路(IC)间的通讯。 
      关于I2C协议的更多内容,可阅读《I2C总线协议》,本博文主要分析I2C波形图,对于I2C的基础知识不在做介绍。

    二、I2C协议标准代码

    2.1 起始信号&停止信号

      起始信号:当 SCL 线是高电平时 SDA 线从高电平向低电平切换。 
      停止信号:当 SCL 线是高电平时 SDA 线由低电平向高电平切换。

    2.1.1 起始信号代码

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    void I2C_Start(void)

    {

        I2C_SDA_High();     //SDA=1

        I2C_SCL_High();     //SCL=1

        I2C_Delay();

        I2C_SDA_Low();

        I2C_Delay();

        I2C_SCL_Low();

        I2C_Delay();

    }

    2.1.2 停止信号代码

    1

    2

    3

    4

    5

    6

    7

    8

    void I2C_Stop(void)

    {

        I2C_SDA_Low();

        I2C_SCL_High();

        I2C_Delay();

        I2C_SDA_High();

        I2C_Delay();

    }

    2.2 发送一个字节

      CPU向I2C总线设备发送一个字节(8bit)数据

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    u8 I2C_SendByte(uint8_t Byte)

    {

        uint8_t i;

     

        /* 先发送高位字节 */

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

        {

            if(Byte & 0x80)

            {

                I2C_SDA_High();

            }

            else

            {

                I2C_SDA_Low();

            }

            I2C_Delay();

            I2C_SCL_High();

            I2C_Delay();

            I2C_SCL_Low();

            I2C_Delay();

     

            if(i == 7)

            {

                I2C_SDA_High();                     /* 释放SDA总线 */

            }

            Byte <<= 1;                             /* 左移一位  */

     

            I2C_Delay();

        }

    } 

    2.3 读取一个字节

      CPU从I2C总线设备上读取一个字节(8bit数据)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    u8 I2C_ReadByte(void)

    {

        uint8_t i;

        uint8_t value;

     

        /* 先读取最高位即bit7 */

        value = 0;

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

        {

            value <<= 1;

            I2C_SCL_High();

            I2C_Delay();

            if(I2C_SDA_READ())

            {

                value++;

            }

            I2C_SCL_Low();

            I2C_Delay();

        }

     

        return value;

    }

    2.4 应答

    2.4.1 CPU产生一个ACK信号

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    void I2C_Ack(void)

    {

        I2C_SDA_Low();

        I2C_Delay();

        I2C_SCL_High();

        I2C_Delay();

        I2C_SCL_Low();

        I2C_Delay();

     

        I2C_SDA_High();

    }

    2.4.2 CPU产生一个非ACK信号

    1

    2

    3

    4

    5

    6

    7

    8

    9

    void I2C_NoAck(void)

    {

        I2C_SDA_High();

        I2C_Delay();

        I2C_SCL_High();

        I2C_Delay();

        I2C_SCL_Low();

        I2C_Delay();

    }

    2.4.3 CPU产生一个时钟,并读取器件的ACK应答信号

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    uint8_t I2C_WaitToAck(void)

    {

        uint8_t redata;

     

        I2C_SDA_High();

        I2C_Delay();

        I2C_SCL_High();

        I2C_Delay();

     

        if(I2C_SDA_READ())

        {

            redata = 1;

        }

        else

        {

            redata = 0;

        }

        I2C_SCL_Low();

        I2C_Delay();

     

        return redata;

    }   

    三、I2C通信时序图解析

      有了上边的I2C总线标准代码的基础,下面我们进入本博文所要讲解的内容,怎么分析I2C的时序图,以O2Micro的OZ9350为例,OZ9350是一款模拟前端(AFE)的IC器件。是一款性价比不错的电源管理芯片,由于其通讯是通过I2C来进行通讯的,所以这里用OZ9350的I2C通讯做例子进行讲解。

    3.1 写数据

      首先我们先来看一下写数据的时序图,如下图所示: 
      将上图中的写数据时序图进行分解,经分解后如下图所示: 

      结合I2C总线协议的知识,我们可以知道OZ9350的I2C写数据由一下10个步骤组成。 
      第一步,发送一个起始信号。 
      第二步,发送7bit从机地址,即OZ9350的地址。此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写。 
      第三步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。 
      第四步,发送寄存器地址,8bit数据。 
      第五步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。 
      第六步,发送一个数据,8bit数据。 
      第七步,产生一个ACK应答信号,此应答信号为从机器件产生的应答信号。 
      第八步,发送一个CRC校验码,此CRC校验值为2、4、6步数据产生的校验码。 
      第九步,既可以发送一个应答信号,也可以发送一个无应答信号,均有从机器件产生。 
      第十步,发送一个停止信号。 
      接下来,按照以上是个步骤,可以写出OZ9350的i2c写数据的函数。代码如下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    u8 I2C_WriteBytes(void)

    {

        I2C_Start();                    //1

     

        I2C_SendByte(Slaver_Addr | 0);  //2

        I2C_WaitToAck();                //3

     

        I2C_SendByte(Reg_Addr);         //4

        I2C_WaitToAck();                //5

     

        I2C_SendByte(data);             //6

        I2C_WaitToAck();                //7

     

        I2C_SendByte(crc);              //8

        I2C_WaitToAck();                //9

     

        I2C_Stop();                     //10

    }

    3.2 读数据

      读数据的时序图如下图所示: 

      读数据的时序图经分解后如下图所示: 

      通过分解后的时序图,可以看到OZ9350的读数据由以下13个步骤组成。 
      第一步,发送一个起始信号。 
      第二步,发送7bit从机地址,即OZ9350的地址。此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写。 
      第三步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。 
      第四步,发送寄存器地址。 
      第五步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。 
      第六步,再次发送一个骑士信号。 
      第七步,发送7bit从机地址,即OZ9350的地址。此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写。 
      第八步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。 
      第九步,读取一个字节(8bit)的数据。 
      第十步,产生一个ACK应答信号,此应答信号为CPU产生。 
      第十一步,读取一个CRC校验码。 
      第十二步,产生一个NACK信号。此无应答信号由CPU产生。 
      第十三步,产生一个停止信号。 
      接下来,由以上分析步骤,可以写出OZ9350的I2C读数据代码。如下所示:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    u8 I2C_ReadBytes(void)

    {

        u8 data;

        u8 crc;

     

        I2C_Start();                    //1

     

        I2C_SendByte(Slaver_Addr | 0);  //2

        I2C_WaitToAck();                //3

     

        I2C_SendByte(Reg_Addr);         //4

        I2C_WaitToAck();                //5

     

        I2C_Start();                   //6

     

        I2C_SendByte(Slaver_Addr | 1);  //7 1-读

        I2C_WaitToAck();                //8

     

        data=I2C_ReadByte();            //9

     

        I2C_Ack();                      //10

     

        crc=I2C_ReadByte();             //11

     

        I2C_NoAck();                    //12

     

        I2C_Stop();                     //13

    }

    四、结语

    写:MCU在数据总线上的数据稳定之后,检测边沿信号(上升沿)写数据到器件;

    读:MCU发出边沿信号(下降沿)告诉器件发送数据,检测到边沿信号之后,器件改变(更新)数据,等待稳定之后MCU读取数据

     

    数据的写操作:图中演示了I2C连续写数据,两个字节的连续写入,更多字节同样

    数据的读操作:在上图中,可以认为写入了设备地址及寄存器地址,再次重启总线后,发送读命令,连续读取两个字节,发送NACK,发送停止信号;

    全文转自:https://www.cnblogs.com/Tangledice/p/7622794.html

    展开全文
  • 本文档详细描述了关于I2C总线协议的起始信号、停止信号、读数据、写数据等多项规定,其中还包括具体的时序图,可以在写硬件代码时进行参考。
  • 示波器分析i2c读写时序图

    千次阅读 2020-06-08 15:47:55
    对于嵌入式开发的朋友来说,I2C协议实在是再熟悉不过了,有太多的器件,采用的都是通过I2C来进行相应的设置。今天,我们就随便聊聊这个I2C协议。 I2C协议中最重要的一点是I2C地址。这个地址有7位和10位两种形式。7...

    转载自:https://blog.csdn.net/huzgd/article/details/6187056

    本篇博客借助示波器对i2c读写时序分析的很详细,图文并茂。


    对于嵌入式开发的朋友来说,I2C协议实在是再熟悉不过了,有太多的器件,采用的都是通过I2C来进行相应的设置。今天,我们就随便聊聊这个I2C协议。

    I2C协议中最重要的一点是I2C地址。这个地址有7位和10位两种形式。7位能够表示127个地址,而在实际使用中基本上不会挂载如此多的设置,所以很多设备的地址都采用7位,所以本文接下来的说明都是基于此。

    I2C还有一个很重要的概念,就是“主—从”。对于从设备来说,它是啥都不干的,更不会自动发送数据;而主设备,则是起到控制作用,一切都是从它开始。

    除了GND以外,I2C有两根线,分别是SDA和SCL,所有的设备都是接到这两根线上。那么,这些设备如何知道数据是发送给它们呢?这就得依靠前面所说到的地址了。设备I2C的地址是固定的,比如0x50,0x60等等。因为只能有127个地址,地址冲突是很常见的,所以一般设备都会有一个地址选择PIN,比如拉高时候为0x50,接地为0x60。如果无论拉高还是接地,都和别的芯片有冲突,那该怎么办呢?答案是:凉拌,没办法。遇到这种情况,只能换芯片了。

    我们来看I2C协议中的数据传输时序图:

    SCL是时钟,SDA承载的是数据。当SDA从1变动到0,而SCL还是1时,表示开始数据传输。接下来的7位,就是设备的地址。紧接着的是读写标志,其为1时是读取,为0则是写。如果I2C总线上存在着和请求的地址相对应的设备,则从设备会发送一个ACK信号通知主设备,可以发送数据了。接到ACK信号后,主设备则发送一个8位的数据。当传输完毕之后,SCL保持为1,SDA从0变换到1时,标明传输结束。

    从这个时序图中可以看到,SCL很重要,并且哪个时钟沿是干嘛的,都是确定好的。比如,前面7个必定是地址,第8个是读写标志,数据传输必须是8位,必须接个ACK信号等等。

    前面的时序图并没有标明数据传输的方向,我们现在看看写操作的数据流向:

    网格的是主设备发送的,白色格子是从设备发送的。从图示中可以看到,对于写操作,从设备都只是发送ACK进行确认而已。

    而读操作的数据流向,就有所不同,如图:



    这时候,从设备除了发送ACK以外,紧跟着的还有数据。

     

    我们用示波器来查看波形图,以便于理解。

    将示波器的X和Y分别接到SDA和SCL,得到波形并分析如图:

    I2C的概念原理网上都有就不说了,这里只把我把两个开发板通过I2C通讯的调试经验记录分享一下。

     

    I2C要求要有一个主设备,负责发起请求和控制时钟;其它为从设备,通过设备ID地址来识别并响应主设备请求。主从设备要轮流控制SDA。一开始我没搞明白这一点,直接加了写I2C数据代码,然后用示波器在SDA和SCL脚测量,却只能找到些凌乱的波形,没有预期的效果。后来把从设备接上,两边写好代码,互相有了响应,这才在示波器上看到波形。

     

    这里我找了一个主设备往从设备写数据的例子,代码如下:

    char buf[128];
    int len;
    
    strcpy(buf,"..huz_hello_i2c/n");
    len=strlen(buf);
    
    //deviceid: 0x3c
    write_i2c(0x3c, buf , len);
    
    

    接收端的代码比较简单,就不贴了。

     

    将示波器的X和Y分别接到SDA和SCL,得到波形并分析如图:

     

    从图中可知写时序如下:

    1. 由主机发起,在SCL为高电平时,SDA由高到低切变,形成开始信号;
    2. 接着是7位地址和一位读写标志,这里7位地址为0111100,即0x3c,正是我们代码中设置的地址ID;最后一位为0表示写操作;
    3. 接着在下一个时钟,主机以高电平状态释放SDA,这时从机响应,将SDA拉低了;
    4. 接着是两个8位数据00101110与响应,即0x2E,正是“.”号的ASCII码,符合预期输出;
    5. 还有其它数据和最后的停止位,图中被截掉了。

    从图中可知,纵向一格是200mV,则SDA和SCL的电平大概就是350mV;由于信号笔上设置了信号x10,因此实际电平应该大概是3.5V(理论上应该是3.3V)。横向一格是25us,10个时钟周期大概用了4格,即4x25us=100us,平均每个时钟周期是10us,可算出传输频率为1/10us=100,000/s,即100k bps。

     

    另外,对于读从设备内容,基本流程是主设备先往从设备写一个命令,然后再输出读取命令,然后才由从设备发送数据。过程类似,不再具体分析了。

     

    下图示例中,主机先向从机写了一个地址命令,然后重新开始并进入读取周期。

     

     

    分析波形可检测出I2C通信工作是否正常,是否符合预期,对我们编程调试诊断有辅助作用。

     

    展开全文
  • i2c时序图详细讲解

    千次阅读 2019-06-30 18:58:29
    https://blog.csdn.net/chm880910/article/details/80086052 https://blog.csdn.net/qq_36554582/article/details/87989756
  • I2C总线时序详解

    千次阅读 2021-05-06 11:21:52
    1显示了嵌入式系统的典型I2C总线。 微控制器代表I2C主控制器,作为主设备,并控制各个从设备,这些从设备包括但不限于,IO扩展器,各种传感器,EEPROM,ADC/DAC等等。 而所有这些都只由主设备的2个引脚控制。 ...
  • i2c时序图

    千次阅读 2013-03-28 08:49:50
  • 用示波器对单片机I2C时序进行图形波形分析的试验小结.docx用示波器对单片机I2C时序进行图形波形分析的试验小结.docx用示波器对单片机I2C时序进行图形波形分析的试验小结.docx用示波器对单片机I2C时序进行图形波形...
  • 用示波器对单片机I2C时序进行图形波形分析的试验小结.pdf用示波器对单片机I2C时序进行图形波形分析的试验小结.pdf用示波器对单片机I2C时序进行图形波形分析的试验小结.pdf用示波器对单片机I2C时序进行图形波形分析的...
  • I2C时序波形

    千次阅读 2022-01-07 10:28:28
    对于嵌入式开发的朋友来说,I2C协议实在是再熟悉不过了,有太多的器件,采用的都是通过I2C来进行相应的设置。今天,我们就随便聊聊这个I2C协议。 I2C协议中最重要的一点是I2C地址。这个地址有7位和10位两种形式。7...
  • IIC(I2C Inter-Intergrated Circuit 集成电路总线) 由Pillphs公司发明的。 IIC也是属于通信的一种,并且也是串行通信(按bit收发数据)。 IIC属于串行总线通信: 只有一根数据线 SDA:Serial DAta 串行数据线...
  • I2C通信时序图解析

    千次阅读 2019-05-18 11:55:13
    二、I2C协议标准代码 2.1 起始信号&停止信号   起始信号:当 SCL 线是高电平时 SDA 线从高电平向低电平切换。   停止信号:当 SCL 线是高电平时 SDA 线由低电平向高电平切换。 2.1.1 起始信号代码 1...
  • 有关I2C总线时序,下面的文章写得很好,推荐阅读 https://www.cnblogs.com/BitArt/archive/2013/05/28/3103917.html#commentform 8位设备地址,8位寄存器地址,8位数据的情况完全够了 下面我想补充的是8位设备...
  • I2C通讯协议及时序

    千次阅读 2017-06-02 13:45:49
    I2C协议介绍 I2C总线,PHILIPS公司定义的协议,由两条总线组成,数据线和时钟线,作为串行总线的一种,因接口所需要的线较少,所以被广泛利用。 一、速率 最高速率:400Kbps。(如果使用硬件I2C接口,可以通过...
  • STM32 使用IO口模拟I2C时序

    千次阅读 多人点赞 2020-04-11 16:16:56
    上一篇《I2C协议详解》 我们了解了I2C的操作流程,这一篇,我们就使用I2C,来对...由硬件产生的I2C时序,我们借助Stm32Cube配置实现便可,我们这一篇,抛开Stm32Cube,手撕代码,根据I2C的时序,一步步地实现I2C对...
  • 示波器分析I2C时序波形

    千次阅读 2019-05-23 22:44:08
    I2C协议中最重要的一点是I2C地址。这个地址有7位和10位两种形式。7位能够表示127个地址,而在实际使用中基本上不会挂载如此多的设置,所以很多设备的地址都采用7位,所以本文接下来的说明都是基于此。 I2C还有一个...
  • 用示波器测量I2C进行时序图、波形等分析

    万次阅读 多人点赞 2017-09-20 17:35:20
    I2C的概念原理网上都有就不说了,这里只把我把两个开发板通过I2C通讯的调试经验记录分享一下。 I2C要求要有一个主设备,负责发起请求和控制时钟;其它为从设备,通过设备ID地址来识别并响应主设备请求。主从设备要...
  • FPGA实现I2C时序详解

    千次阅读 2020-07-14 22:33:36
    I2C时序也花了一两天的时间才从搞懂时序到看懂代码。这里记录一下学习过程中的迷惑。 I2C总线是由两根线组成:一根SCL,一根SDA,可以实现少量数据的读写,例如对某一外设进行配置,这种情况是对该外设某些寄存器...
  • STM32模拟I2C时序读写EEPROM精简版

    千次阅读 2018-01-20 15:57:10
    工程介绍:主要文件在USER组中,bsp_i2c_ee.c,bsp_i2c_ee.h,bsp_eeprom.c,bsp_eeprom.h和main.c,其中bsp_i2c_ee.c中主要时基本的模拟I2C时序,而bsp_eeprom.c中主要利用前一个文件中定义的基本操作,进行EE...
  • I2C验证的时序特性问题

    千次阅读 2021-08-13 18:19:56
    I2C通常支持三种速率模式:标准(100kb/s)/快速(400kb/s)/高速模式(3.4Mb/s)。CCI(Camera Control Interface)是为I2C的子集,仅支持标准和快速两种模式,相对速率较低。因此在采用CCI接口时,应考虑I2C的建立保持时间...
  • I2C 协议之软件模拟时序

    千次阅读 2017-08-01 12:04:29
    1.1 I2C 简介   I2C 总线时 PHILIPS 公司推出的一种串行总线,具备多主机系统所需的包括总线仲裁和高低速器件同步功能的高性能串行总线。它只需要两跟双向的信号线,一根数据线 SDA,一个是时钟线 SCL。在 I2C ...
  • DSP 2803x IIC/I2C总线

    千次阅读 2020-08-06 21:10:54
    参考手册:TMS320x2803x, Piccolo Technical Reference Manual.pdf ...IIC/I2C 总线术语的定义 术语 描述 发送器 发送数据到总线的器件 接收器 从总线接收数据的器件 主机 初始化
  • I2C 时序详解,精确到每一个时钟

    万次阅读 多人点赞 2017-06-28 21:47:28
    I2C时序 3.1 字节格式 发送到SDA 线上的每个字节必须为8 位,每次传输可以发送的字节数量不受限制。每个字节后必须跟一个响应位。首先传输的是数据的最高位(MSB),如果从机要完成一些其他功能后(例如一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,487
精华内容 20,194
关键字:

i2c时序图