I2C协议

1 IIC 简介

  I2C(Inter-Integrated Circuit) 是内部整合电路的称呼, 是一种串行通讯总线, 使用多主从架构, 由飞利浦公司在1980年为了让主板、 嵌入式系统或手机用以连接低速周边装置而发展。 I2C的正确读法为"I-squared-C" , 而"I-two-C"则是另一种错误但被广泛使用的读法, 在中国则多以"I方C"称之。 I2C 总线支持任何IC 生产过程(NMOS CMOS、 双极性) 。 两线――串行数据(SDA) 和串行时钟 (SCL) 线在连接到总线的器件间传递信息。 每个器件都有一个唯一的地址识别(无论是微控制器——MCU、 LCD 驱动器、 存储器或键盘接口) , 而且都可以作为一个发送器或接收器(由器件的功能决定) 。在 CPU 与CPU之间,CPU与被控 IC 之间、IC 与 IC 之间进行双向传送。
  注意:RS485通信支持的是一主多从模式,IIC通信支持的是多主从模式。RS485不支持多主机总线仲裁,总线上通常只有一台主机,且从机不能当主机;IIC通信支持多主机总线仲裁,允许多个主设备连接到同一条总线上,当多个主设备尝试同时控制总线时,IIC协议会进行仲裁,以确定哪个设备能够成为总线的主控设备。任何一个设备都可以作为主机或从机,但是同一时间只有一个设备可以成为主机。

2 IIC 物理层

  I2C 通讯设备之间的常用连接方式见下图:在这里插入图片描述
  它的物理层有如下特点:
  (1)、它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
  (2)、一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
  (3)、每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。
  (4)、总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
  (5)、 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。
  (6)、具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
  (7)、连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制 。
  第四条解释:当I2C设备空闲时,它们会把自己的总线接口设置为高阻态,也就是说,它们不会驱动总线,而是让总线保持它的当前状态。这就像一个电子开关,把它设置为“高阻态”就像是把它关掉,不让电流通过。当所有I2C设备都空闲,并且都把它们的总线接口设置为高阻态时,上拉电阻就会起作用,把总线的电平拉高到接近正电源的电平。这样做有一个好处:当所有设备都空闲时,总线的电平会被上拉电阻拉高,这样就可以比较容易地检测到总线上是否有设备正在尝试发送数据。因为如果有设备正在发送数据,它会驱动总线到低电平,这样总线的电平就会被拉低,与上拉电阻试图维持的高电平形成对比。这种对比使得检测总线的状态变得比较简单。
  第七条解释:根据总线的最大电容限制来确定连接到相同总线的IC数量需要考虑每个IC的电容负载。一般来说,每个IC的电容负载会在其数据手册或规格书中给出。可以将每个IC的电容负载相加,以确保总电容不超过400pF。另外,还需要考虑总线上其他元件的电容负载,如连接电缆、连接器等。这些元件的电容负载也需要计入总电容中。当总线上的电容负载增加时,总线的传输速率会逐渐下降。为了确保总线的稳定工作,规定了总线的最大电容负载,即在连接到同一条总线的所有IC和设备的电容之和不能超过400pF。如果超过了这个限制,可能会导致数据传输错误或不稳定,甚至可能损坏总线或连接的IC。因此,在设计电子系统时,需要仔细考虑总线的电容负载和连接的IC数量,以确保系统的稳定性和可靠性。

3 IIC 协议层

I2C 的协议定义了通讯的读写过程,起始和停止信号、数据有效性、地址及数据方向、响应、仲裁、时钟同步等环节。

(1)、I2C 基本读写过程

先看看 I2C 通讯过程的基本结构,它的通讯过程见下图:在这里插入图片描述
在这里插入图片描述
  I2C 通讯复合格式在这里插入图片描述在这里插入图片描述
这些图表示的是主机和从机通讯时, SDA 线的数据包序列。
  A、S 表示由主机的 I2C 接口产生的传输起始信号(S),这时连接到 I2C 总线上的所有从机都会接收到这个信号。
  B、起始信号产生后,所有从机就开始等待主机紧接下来广播 的从机地址信号(SLAVE_ADDRESS)。 在 I2C 总线上,每个设备的地址都是唯一的, 当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号。根据 I2C 协议,这个从机地址可以是 7 位或 10 位。
  C、在地址位之后,是传输方向的选择位,该位为 0(W) 时,表示后面的数据传输方向是由主机传输至从机,即主机往从机中写数据。该位为 1(R) 时,则相反,即主机由从机读数据。
  D、从机接收到匹配的地址后,从机会返回一个应答(ACK)或非应答(NACK)信号,只有接收到应答信号后,主机才能继续发送或接收数据。
  E、若配置的方向传输位为“写数据”方向, 广播完地址,接收到应答信号后, 主机开始正式向从机传输数据(DATA),数据包的大小为 8 位,主机每发送完一个字节数据,都要等待从机的应答信号(ACK),重复这个过程,可以向从机传输 N 个数据,这个 N 没有大小限制。当从机不能再接收主机发送的数据时,就向主机返回一个非应答信号(NACK),主机向从机发送一个停止传输信号§,表示不再传输数据;当数据传输结束时,主机向从机发送一个停止传输信号§,表示不再传输数据。
  F、若配置的方向传输位为“读数据”方向, 广播完地址,接收到应答信号后, 从机开始向主机返回数据(DATA),数据包大小也为 8 位,从机每发送完一个数据,都会等待主机的应答信号(ACK),重复这个过程,可以返回 N 个数据,这个 N 也没有大小限制。当主机希望停止接收数据时,就向从机返回一个非应答信号(NACK),主机向从机发送一个停止传输信号§,则从机自动停止数据传输;当数据传输结束时,主机向从机发送一个停止传输信号§,表示不再传输数据。
  G、除了基本的读写, I2C 通讯更常用的是复合格式,该传输过程有两次起始信号(S)。一般在第一次传输中,主机通过 SLAVE_ADDRESS 寻找到从设备后,发送一段“数据”,这段数据通常用于表示从设备内部的寄存器或存储器地址(注意区分它与 SLAVE_ADDRESS 的区别);在第二次的传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。

(2)、通讯的起始和停止信号

  前文中提到的起始(S)和停止§信号是两种特殊的状态,见下图。当 SCL 线是高电平时 SDA 线从高电平向低电平切换,这个情况表示通讯的起始。当 SCL 是高电平时 SDA线由低电平向高电平切换,表示通讯的停止。起始和停止信号一般由主机产生。
   I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生(意味着从设备不可以主动通信?所有的通信都是主设备发起的,主设备可以发出询问的command,然后等待从设备的通信)。
  起始和结束信号产生条件:总线在空闲状态时,SCL和SDA都保持着高电平。当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个停止条件。
  在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备将释放总线,总线再次处于空闲状态。起始和结束如图所示:
在这里插入图片描述
  在了解起始条件和停止条件后,我们再来看看在这个过程中数据的传输是如何进行的。前面我们已经提到过,数据传输以字节为单位。主设备/从设备在SCL线上产生每个时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备/主设备将拉低SDA线,回传给主设备/从设备一个应答位, 此时才认为一个字节真正的被传输完成。当然,并不是所有的字节传输都必须有一个应答位,比如:当主设备/从设备不能再接收从设备/主设备发送的数据时,主设备/从设备将回传一个否定应答位。数据传输的过程如图所示:

在这里插入图片描述
  在前面我们还提到过,I2C总线上的每一个设备都对应一个唯一的地址,主从设备之间的数据传输是建立在地址的基础上,也就是说,主设备在传输有效数据之前要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,**只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据。**向指定设备发送数据的格式如图所示:(每一最小包数据由9bit组成,8bit内容+1bit ACK, 如果是地址数据,则8bit包含1bit方向)在这里插入图片描述

(3)、数据有效性

  I2C 使用 SDA 信号线来传输数据,使用 SCL 信号线进行数据同步,见下图所示。 SDA数据线在 SCL 的每个时钟周期传输一位数据。传输时, SCL 为高电平的时候 SDA 表示的数据有效,即此时的 SDA 为高电平时表示数据“1”,为低电平时表示数据“0”。当 SCL为低电平时, SDA 的数据无效,一般在这个时候 SDA 进行电平切换,为下一次表示数据做好准备。在这里插入图片描述
  每次数据传输都以字节为单位,每次传输的字节数不受限制。

(4)、地址及数据方向

  I2C 总线上的每个设备都有自己的独立地址,主机发起通讯时,通过 SDA 信号线发送设备地址(SLAVE_ADDRESS)来查找从机。 I2C 协议规定设备地址可以是 7 位或 10 位,实际中 7 位的地址应用比较广泛。紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/W),第 8 位或第 11 位。数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。见下图:
在这里插入图片描述
  读数据方向时,主机会释放对 SDA 信号线的控制,由从机控制 SDA 信号线,主机接收信号,写数据方向时, SDA 由主机控制, 从机接收信号。

(5)、响应

  I2C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。作为数据接收端时,当设备(无论主从机)接收到 I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。见下图:在这里插入图片描述
  传输时主机产生时钟,在第 9 个时钟时,数据发送端会释放 SDA 的控制权,由数据接收端控制 SDA,若 SDA 为高电平,表示非应答信号(NACK),低电平表示应答信号(ACK)。
  读数据方向时,主机会释放对 SDA 信号线的控制,由从机控制 SDA 信号线,主机接收信号,写数据方向时, SDA 由主机控制, 从机接收信号。

(6)、仲裁

  在I2C总线的仲裁过程中,其他主控器也会参与。当多个主控器同时尝试控制总线时,他们会同时发送数据。每个主控器在发送每个数据位时都会检测SDA线上的电平。如果检测到的电平与自己发送的电平相符,该主控器就会继续发送数据。如果检测到的电平与自己发送的电平不符,该主控器就会停止发送数据,并等待一段时间后再尝试重新获取总线的控制权。
  在仲裁过程中,如果有一个主控器发送了低电平,那么由于“线与”的逻辑功能,SDA线上的电平就会被拉低。因此,其他发送高电平的主控器会检测到与自己发送的电平不符的情况,从而停止发送数据。这样,发送低电平的主控器就会赢得仲裁,成为总线的控制者。
  直接举例。设主机1将向address为0b10100111的从机发送数据,主机2将向addres为0x10101000的从机发送数据。两者都占有总线并同时向SDA写入数据。注意I2C发送的顺序是MSB->LSB(先发送高位)。两者的前四位数据相同,而当发送进行到第五个时钟周期时,master1的第五位为0,而master2的第五位为1,此时根据线与特性,SDA总线的电平会被master1拉低。master2会检测到自己要发送的电平和总线的实际电平不符,从而获知有其他主机正在发送,随之停止后续的发送,让出总线的归属权。若两主机向相同的地址写入数据,那么仲裁过程将继续,直到在后续的数据位中决出总线的归属权(仍然是通过上述的方法)。
  仲裁不能发生在start和stop段,否则行为是未定义的。即倘若两个主机向相同的地址写入相同的数据,那么并不能决出总线的归属权,这时候的行为就是未定义的,应该避免这种情况发生
  需要注意的是,I2C的仲裁是通过采样SDA完成的,因此不会破坏数据的有效性,通信不会停止,也不会有数据帧丢失。但是I2C不具有主机优先级的设定,因为总线的归属权是根据主机发送的数据确定的,因此无法提前为每个主机设定发送或接收的优先级。

(6)、时钟同步

  在I2C通信中,时钟同步主要在以下情况下发生:
  1 当主机的速度快于从机的速度时。主机传输数据的速率高于从机接收或发送数据的速率时,从机可能无法及时跟上主机的节奏。此时,从机可以通过将SCL主动拉低来通知主机降低传输速率,延长SCL低电平时间。当主机发现SCL电平被拉低时,它会进入等待状态,直到从机完成操作并释放SCL线。这就需要时钟同步来确保双方设备的速率匹配。
  2 当从机需要处理其他事情而不能及时地从主机接收数据或者向主机发送数据时。例如,当从机正在进行其他内部操作或处理其他任务时,它可能无法立即响应主机的数据传输请求。此时,从机也可以通过将SCL拉低来通知主机等待,直到从机完成当前操作并准备好接收或发送数据。时钟同步确保了在这种情况下数据传输的顺利进行。
  3 在多主机系统中,当多个主设备尝试同时控制同一个从设备时。在这种情况下,多个主设备可能会同时尝试在SCL线上生成自己的时钟来控制同一个从设备。为了避免冲突和数据传输错误,需要通过时钟同步来确保只有一个主设备能够控制SCL线并进行数据传输。

  总之,时钟同步在I2C通信中起着重要作用,它确保了数据传输的可靠性和准确性,特别是在主机和从机速度不匹配或多主机系统中尤为重要。

  注意1:时钟同步的主要目的是在主机和从机速度不匹配的情况下,通过调整主机的传输速率来适应从机的速度,以确保数据的可靠传输。当从机速度快于主机时,可将SCL拉低以延长数据传输周期,从而适应主机的速度,而不需要进行时钟同步。
  注意2:在I2C通信中,时钟同步主要在几种情况可能同时发生。

   多主机系统时钟同步的举例如下:
  SCL是由主机产生的时钟信号,用于和从机确定数据发送和采样的时间点。倘若处在仲裁期间,会有多个主机同时发送往SCL上发送时钟信号。两个主机配置的通信速率可能不同,因此时钟频率必然不同;即使配置了相同的通信速率,两者开始发送数据的时间也不同。此时时钟信号具体如何确定就要通过clock synchronization的机制。
  在总线空闲的时候,SCL被上拉电阻拉高。开始通信后,主机的时钟信号接入SCL中。如下图所示,有两个主机(时钟信号分别为CLK1和CLK2)都认为主机空闲,因此开始将时钟信号输入SCL。同步分为以下五个阶段:
在这里插入图片描述
  1 CLK1率先变为低电平,由于线与特性CLK2也变成低电平。
  2 但是CLK2的低电平时间更长(时钟周期更长,CLK1的周期更短),即使主机1内部的CLK1已经变成高电平,SCL的实际电平仍然和CLK2保持一致。此时,主机1将会检测到这一情况,并从此时开始计数(计算低电平持续的时间,即下图中的wait state,稍后用)
  3 CLK2迎来高电平之后,主机1内部的wait state结束,因为两者都为高,因此SCL总线进入高电平,两个主机内部都会开始对高电平持续的时间进行计数。
  4 随后,CLK1会比CLK2先回到低电平(此时CLK1的周期仍然比CLK2更短)。
  5 现在,CLK1以及获得了需要延长的低电平时间,CLK2也获得了需要减短的高电平时间(都是通过刚才的计数获得的),两个主机会根据之前的计数重新调整自己的时钟周期,从而完成时钟同步。

4 IIC 应用

(1)、软件IIC和硬件IIC

  软件IIC:软件IIC通信指的是用单片机的两个I/O端口模拟出来的IIC,用软件控制管脚状态以模拟I2C通信波形,软件模拟寄存器的工作方式。
  硬件IIC:一块硬件电路,硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,硬件(固件)I2C是直接调用内部寄存器进行配置。
  硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。

(2)、软件IIC程序

①、 iic.h文件

#ifndef __IIC_H
#define __IIC_H
#include "sys.h"

//IO方向设置 
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;} //  输入
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;} //  输出	

//IO操作函数	 
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //输入SDA 

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号
 
#endif

②、iic.c文件

初始化IIC
#include "iic.h"
#include "delay.h"

//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
}
产生IIC起始信号
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}
数据传输

  I2C 总线在数据传输的时候要保证在 SCL 高电平期间,SDA 上的数据稳定,因此 SDA 上的数据变化只能在 SCL 低电平期间发生。

//IIC发送一个字节
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)          //一位一位的传输
    {              
        IIC_SDA=(txd&0x80)>>7;  //从最高位开始传输
        txd<<=1; 	     //txd=txd<<1
		delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}
应答信号
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}		
等待信号
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	//感觉有问题,已经配置成输入了,又再次输出,因为是正点原子源代码,暂不处理。
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 

5 软件IIC 使用过程中要注意的一些问题

(1)配置IIC时,IO设置成什么模式?

  图为STM32f103-GPIO
在这里插入图片描述在这里插入图片描述
  IIC是两线式串口总线,分别为SCL线和SDA线,对主机而言SCL的IO口要实现输出高低电平的功能,SDA的IO口要实现输出高低电平和输入扫描的功能,我们配置IIC都是使用什么配置???
  1.IIC电路存在上拉电阻.**我们得先明白什么是开漏输出,一句话,开漏输出如果不接上拉电阻是没有输出高电平的能力的,只有输出低电平的能力,然IIC电路存在上拉电阻,让配置开漏输出成为了可能.当不连接上拉电阻时,输出逻辑1,P-MOS未激活,输出电路开路,不能输出高电平;输出逻辑0,N-MOS激活,输出低电平.当连接上拉电阻时,输出逻辑1,P-MOS未激活,有上拉电压存在,输出高电平;输出逻辑0,N-MOS激活,输出低电平.
  2.根据上图两张图GPIO的输入输出配置,当只有输出配置时,输入检测功能还是可以存在使用的.所以我们完全有理由给SCL和SDA都配置输出功能即可实现IIC,不用再给SCL和SDA单独进行输入配置.
  3.配置方式
  SCL线可以配置推挽输出,开漏输出(有上拉电压存在)都可,因为不用兼具输入扫描功能;
  SDA配置成推挽输出也行,但在进行检测前要将SDA配置为输入模式(否者,当要实现输入检测时,就会受到输出电路没有关闭的影响,因为之前的输出电平还是存在的,造成输入电路和输出电路的短接等现象.)
  如果将SDA配置为开漏输出(有上拉电压存在),可能就不需要在检测SDA电平时再将其配置为输入模式(当需要输入检测时输出逻辑1,p-MOS未激活,使输出电路开路,不对输入电路产生影响.)

   前面都是一些理论分析,正常在使用中都将SDA和SCL都设置成开漏输出,并外接上拉电阻,这样使用最保险,稳定性最强,出问题最少。

(2)配置IIC时,上拉电阻设置多大?

  IIC信号的上拉电阻阻值不能太大,因为IIC芯片SCL和SDA引脚都存在寄生电容,同时SDA和SCL信号的走线也会有寄生电容,整个IIC总线上相当于接了一个负载电容Cl。在这里插入图片描述
  上拉电阻过大,IIC总线高电平的驱动能力差,总线电平从0到1变化时,等效为这个RC的充电电路,上拉电阻越大,波形上升沿会变缓,一定程度会影响IIC的时序,可能会出现误码。所以这个上拉电阻不能太大。在这里插入图片描述  IIC SDA和SCL信号的上升时间和总线电容在不同的模式下有不同的要求,大家可以看下这个表。在这里插入图片描述  IIC总线信号上升时间可以根据公式Tr=0.8473RCl Cl就是IIC总线的等效负载电容
  IIC信号上拉电阻也不能太小,如果太小了,当IIC引脚输出低电平时,灌进芯片IIC 引脚的电流会变大,可能会使IIC信号线的低电平变大,同时IO口电流过大还可能烧坏芯片。
在这里插入图片描述
  我们一般要求,IIC引脚低电平时,流过芯片IIC引脚的电流小于3mA,所以如果是3.3V上拉的话,这个电阻就要R>(3.3-VoL)l3KΩ=0.96KΩ ,其中VoL是IIC引脚为低电平时的最大电压,一般是0.4V。再加上前面的这个公式我们就可以确定这个上拉电阻的取值范围。在这里插入图片描述

电源电压决定上拉电阻的最小值,总线负载电容决定上拉电阻的最大值。

  IIC信号上拉电阻取值常用的值就是4.7K,一般小于10K,大于1K,如果IIC总线比较长,从设备比较多,可以适当降低电阻。
  如果IIC总线接了很多IIC设备,是不是每个IIC设备都要加上拉电阻?在这里插入图片描述
  答案是否定的,我们只要在SDA和SCL总线上合适的位置各加一个上拉电阻即可,如果每个设备都加上拉,相当于这些电阻是并联在一起了,减小了电阻值。至于上拉电阻的位置一般没有特别的要求。一般加在IIC的末端。
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值