I2C总线介绍

1、首先I2C这是个什么玩意?

  I2C首先百度上的定义是双向二线制同步串行总线。它只需要两根线即可在连接与总线上的器件之间传送信息。

  当然在我看来,I2C首先是一个通信接口,同理通信接口就是用于模块之间的通信的,同SPI接口学习思路一样,首先明白它是一个接口,然后再理解它是一个怎样的接口。

  I2C(Inter - Integrated Circuit)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息(当然设备必须支持I2C接口)。具体在应用的时候总线上的设备节点分为主机和从机两种角色。 

  在物理上传统标准的I2C接口定义:

  除去地线外,人民常说的只有两根线:SDA和SCL,SDA是串行数据线,SCL是串行时钟线,都是双向IO线

  接口电源为开漏输出,需通过上拉电阻接电源VCC,当总线空闲时,两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电器。在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容,而线路中电容会影响总线传输速度。当电容过大时,有可能造成传输错误,所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。

  其实I2C总线上的每一个器件内部的SDA、SCL引脚电路结构都是相同的,引脚的输出驱动与输入缓冲连在一起,输出为漏极开路的场效应管、输入缓冲为一个高输入阻抗的同相器。这种电路具有两个特点:(1)由于SDA、SCL为漏极开管电路,借助于外部的上拉电阻实现了信号的线与逻辑

  (2)引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致。为“时钟同步”和“总线仲裁”提供硬件基础

  

 

 

   I2C标准连接如下图:

  

 

 

   模拟I2C与硬件I2C有什么区别?

  原理上:硬件I2C(提供专门的SDA,SCL口)的时钟是由系统产生的,一般由晶振分频产生。模拟I2C通过编程模拟时钟线和数据线

  控制上:硬件I2C通过硬件中断实现各种操作。模拟I2C没有中断的概念,通过IO接口电平置高置低来实现写入和读取

  性能上:硬件模式更高效更稳定

  硬件I2C比软件I2C速度快很多,占用时间也少,并且硬件I2C使用简单,只需要将数据送到指定寄存器就可以了,不需要自己实现时序

  除了上述基本模式(串行的8位双向数据传输位速率在标准模式下可达100Kbit/s)外,快速模式下可达400Kbit/s,高速模式下可达3,4Mbit/s。这两种模式在硬件电路和软件协议上都有变化可参考百度百科

 

  二、这个到底有什么用?

  上面其实也说过,就是为了通信,同样道理,既然是通信肯定要遵循一定的通讯协议才行,否则双方都听不懂对方的话,正如你讲乌克兰语,我讲法语,大家都听不懂。

  

  三、怎么用啊

  其实谈及怎么用,主要是I2C总线协议,协议内容相对比较多,但其实并不是特别复杂,本文主要概括的讲解下常用到的地方,针对大部分嵌入式软件开发者涉及到的部分内容。具体详细协议内容可以参考https://wenku.baidu.com/view/79bd6a87bceb19e8b8f6ba68.html百度文库

  接下来说的都是协议,学习计算机这块千万不要刨根问底问个底朝天,因为这一块内容实在太多,每走一步都是一个深坑,所以不要问为什么这样,我也不知道,只需知道怎么用就行。

  首先连接在总线上的节点设备有两种角色:主机模式和从机模式。同一时刻只能有一个节点处于主机模式,其它节点处于从机模式。总线上数据的传送都是由主机发起。I2C总线是没有片选信号线的,所以也得通过协议来找到对应操作的芯片。主器件用于启动总线传输数据,并产生时钟以开放传送的器件,此时任何被寻址的器件都被认为是从器件,在总线上主和从、发和手的关系是不恒定的,而取决于此时数据传送方向。如果主机要发送数据给器件,则主机首先寻址从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件,然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下,主机负责产生时钟和终止数据传送。

 

  I2C数据传输基本过程:

  1.主机首先开始发送信号

  2.主机紧接着发送从机地址信息(一个字节),该字节信息中的最低位为读写控制码:1为读,0为写。高7位为从机设备的器件地址

  3.从机然后发出确认信息

  4.主机开始发送信号数据,每当发完一个字节数据后,从机设备给主机发送确认信号

  5.主机最后发送停止信号。

  START开始信号:在SCL时钟线为高电平时,SDA数据线由高变低,产生一个开始信号

  STOP  停止信号:在SCL时钟线为高电平时,SDA数据线由低变高,产生一个停止信号

  ACK确认信号: 当主机写从机设备时,每次写完一个字节,如果数据正确,从机设备将在下一个时钟周期将数据线拉低,来通知主机操作有效。

          当主机读从机设备时,每次正确读完一个字节后,主机将在下一个时钟周期同样也要讲数据线拉低,发出确认信号,来通知从机所发数据以收到

  总之,SCL信号必须要由主机发送

  注意:在读从机设备时,当主机在最后一个字节数据接收完后,不在发送确认信号,直接发送停止信号。还有就是任何时候SCL时钟线为高电平的时候,SDA数据上的电平变化都被认为是起始信号和停止信号,所以数据的改变必须要在时钟为低电平时改变

  

 

 

   I2C数据格式:有两种寻址数据格式:7bit和10bit格式。还有一种重复开始信号寻址格式,如下图

   

 

 

  下面是I2C读写流程:

  I2C写操作寄存器的流程 :

  1.主机发送START开始信号

  2.主机发送从机设备地址信息(I2C addr(7bit)和w操作0(1bit)),等待ACK确认信号

  3.从机发送ACK确认信号

  4.主机发送寄存器地址信息(reg addr(8bit)),等待ACK确认信号

  5.从机发送ACK确认信号

  6.主机发送数据(8bit),即也是要写入寄存器中的数据,等待ACK确认信号

  7.从机发送ACK确认信号

  8.其中第4步到第7步可以重复多次,即顺序操作写多个寄存器

  9.主机发起STOP停止信号

   

  I2C读操作寄存器的流程:

  1.主机发送START信号

  2.主机发送从机设备地址信息(I2C addr(7bit)和w操作0(1bit)),等待ACK确认信号

  3.从机发送ACK确认信号

  4.主机发送寄存器地址信息(reg addr(8bit)),等待ACK确认信号

  5.从机发送ACK确认信号

  6.从机发送数据(8bit),即寄存器里的值

  7.主机发送ACK确认信号

  8.其中第4步到第7步可以重复多次,即顺序读多个寄存器

 

  上述通讯流程模拟I2C跟硬件I2C都类似,不同的地方在于读写

  下面的代码是模拟I2C发送数据:

  void I2C_WriteCmd(unsigned char cmd)

  {

    unsigned char i = 8, temp = 0;

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

    {

      //管脚拉低

      temp = cmd & 0x80;

      if(temp == 0)

      {

        管脚拉低

      }

      else

      {

        管脚拉高

      }

    管脚拉高

    cmd << = 1;

    }

  }

  上面就是通过时钟线SCL和数据SDA的高低电平来传入数据

  而硬件I2C直接通过TXBUF来发送

  补充一点,主机对从机的读写是通过设备地址信息中的1bit位来实现的,简单来说下I2C设备地址

  具体格式如下:

  B7 D6 D5 D4 D3 D2 D1 D0

  1.器件类型由:D7-D4共四位决定的。这是由半导体厂家生产时就已固定此类型的了,也就是说这4位是已固定的

  2.用户自定义地址码:D3-D1共三位决定,这是用户自己决定的,通常的作法如EEPROM这些器件是由外部的IC的三个引脚所组合电平决定的。这也就是寻址码

  3.最低一位就是R/W位

  

posted @ 2020-09-26 18:22  青团青  阅读(2669)  评论(0编辑  收藏  举报