IIC原理学习笔记

学习自-

小旋   IIC原理超详细讲解---值得一看

本文为CSDN博主「Z小旋」的原创文章

原文链接:https://blog.csdn.net/as480133937/article/details/105366932

IIC(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。

在 CPU 与被控 IC 之间、IC 与 IC 之间进行双向传送,高速 IIC 总线一般可达 400kbps 以上。
 这里要注意IIC是为了与低速设备通信而发明的,所以IIC的传输速率比不上SPI

IIC一共有只有两个总线: 一条是双向的串行数据线SDA,一条是串行时钟线SCL

SDA(Serial data)是数据线,D代表Data也就是数据,Send Data 也就是用来传输数据的

SCL(Serial clock line)是时钟线,C代表Clock 也就是时钟 也就是控制数据发送的时序的
所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。I2C总线上的每个设备都自己一个唯一的地址,来确保不同设备之间访问的准确性。

IIC主要特点:

1、I2C主、从设备划分:基本上谁控制时钟线(即控制SCL的电平高低变换)谁就是主设备。

        IIC主设备功能:主要产生时钟,产生起始信号和停止信号

        IIC从设备功能:可编程的IIC地址检测,停止位检测

2、IIC的一个优点是它支持多主控(multimastering), 其中任何一个能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。

当然,在任何时间点上只能有一个主控。

3、支持不同速率的通讯速度,标准速度(最高速度100kHZ),快速(最高400kHZ)

4、SCL和SDA都需要接上拉电阻 (大小由速度和容性负载决定一般在3.3K-10K之间) 保证数据的稳定性,减少干扰。

5、IIC是半双工,而不是全双工 ,同一时间只可以单向通信

为了避免总线信号的混乱,要求各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出。这一点在等下我们会讲解

IIC的高阻态
漏极开路(Open Drain)即高阻状态,适用于输入/输出,其可独立输入/输出低电平和高阻状态,若需要产生高电平,则需使用外部上拉电阻;

高阻状态:高阻状态是三态门电路的一种状态。逻辑门的输出除有高、低电平两种状态外,还有第三种状态——高阻状态的门电路。电路分析时高阻态可做开路理解。

我们知道IIC的所有设备是接在一根总线上的,那么我们进行通信的时候往往只是几个设备进行通信,那么这时候其余的空闲设备可能会受到总线干扰,或者干扰到总线,怎么办呢?

为了避免总线信号的混乱,IIC的空闲状态只能有外部上拉, 而此时空闲设备被拉到了高阻态,也就是相当于断路, 整个IIC总线只有开启了的设备才会正常进行通信,而不会干扰到其他设备。


IIC器件地址: 每一个IIC器件都有一个器件地址,有的器件地址在出厂时地址就设定好了,用户不可以更改,比如OV7670的地址为0x42。有的器件例如EEPROM,前四个地址已经确定为1010,后三个地址是由硬件链接确定的,所以一IIC总线最多能连8个EEPROM芯片。

IIC物理层总结:

I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,SCL和SDA被上拉电阻Rp拉高,使SDA和SCL线都保持高电平。

I2C通信方式为半双工,只有一根SDA线,同一时间只可以单向通信,485也为半双工,SPI和uart通信为全双工。
 

IIC的协议层
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号

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

 

IIC的通信协议流程: 

初始(空闲)状态:

因为IIC的 SCL 和SDA 都需要接上拉电阻,保证空闲状态的稳定性

所以IIC总线在空闲状态下SCL 和SDA都保持高电平

void IIC_init()       //IIC初始化

{

       SCL=1; //首先把时钟线拉高

       delay_us(4);//延时函数

       SDA=1; //在SCL为高的情况下把SDA拉高

       delay_us(4); //延时函数

}

开始信号:

SCL保持高电平,SDA由高电平变为低电平后,延时(>4.7us),SCL变为低电平。

 

//产生IIC起始信号
//1.先拉高SDA,再拉高SCL,空闲状态
//2.拉低SDA
void IIC_Start()         //启动信号

{
       SDA=1; //确保SDA线为高电平
       delay_us(5);
       SCL=1;  //确保SCL高电平
       delay_us(5);
       SDA=0; //在SCL为高时拉低SDA线,即为起始信号
       delay_us(5);
       SCL=0;   //钳住I2C总线,准备发送或接收数据 
    
}

停止信号

停止信号:SCL保持高电平。SDA由低电平变为高电平

//产生IIC停止信号
//1.先拉低SDA,再拉低SCL
//2.拉高SCL
//3.拉高SDA
//4.停止接收数据
void IIC_Stop(void)
{

	IIC_SCL=0;
	IIC_SDA=0;    //STOP:当SCL高时,数据由低变高
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;    //发送I2C总线结束信号
	delay_us(4);							   	
}

 在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备将释放总线,总线再次处于空闲状态。

数据有效性:

IIC信号在数据传输过程中,当SCL=1高电平时,数据线SDA必须保持稳定状态不允许有电平跳变,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

SCL=1时 数据线SDA的任何电平变换会看做是总线的起始信号或者停止信号。

IIC传输数据的过程中,SCL时钟线会频繁的转换电平,以保证数据的传输。

应答信号:

每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,

应答信号:主机SCL拉高,读取从机SDA的电平,为低电平表示产生应答

应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;
应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
**每发送一个字节(8个bit)**在一个字节传输的8个时钟后的第九个时钟期间,接收器接收数据后必须回一个ACK应答信号给发送器,这样才能进行数据传输。

应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答!

 

//主机产生应答信号ACK
//1.先拉低SCL,再拉低SDA
//2.拉高SCL
//3.拉低SCL## 标题
void I2C_Ack(void)
{
   IIC_SCL=0;   //先拉低SCL,使得SDA数据可以发生改变
   IIC_SDA=0;   
   delay_us(2);
   IIC_SCL=1;
   delay_us(5);
   IIC_SCL=0;
}


//主机不产生应答信号NACK
//1.先拉低SCL,再拉高SDA
//2.拉高SCL
//3.拉低SCL
void I2C_NAck(void)
{
   IIC_SCL=0;   //先拉低SCL,使得SDA数据可以发生改变
   IIC_SDA=1;   //拉高SDA,不产生应答信号
   delay_us(2);
   IIC_SCL=1;
   delay_us(5);
   IIC_SCL=0;
}

等待应答信号:

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
char IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	 
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(IIC_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 

IIC数据传送

数据传送格式:

SDA线上的数据在SCL时钟“高”期间必须是稳定的,只有当SCL线上的时钟信号为低时,数据线上的“高”或“低”状态才可以改变。输出到SDA线上的每个字节必须是8位,数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。

当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位ACK, 此时才认为一个字节真正的被传输完成 ,如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。

IIC写数据:

 

 

多数从设备的地址为7位或者10位,一般都用七位。
八位设备地址=7位从机地址+读/写地址,

再给地址添加一个方向位位用来表示接下来数据传输的方向,

0表示主设备向从设备(write)写数据,

1表示主设备向从设备(read)读数据

IIC的每一帧数据由9bit组成,

如果是发送数据,则包含 8bit数据+1bit ACK,

如果是设备地址数据,则8bit包含7bit设备地址 1bit方向

在起始信号后必须传送一个从机的地址(7位) 1~7位为7位接收器件地址,第8位为读写位,用“0”表示主机发送数据(W),“1”表示主机接收数据 (R), 第9位为ACK应答位,紧接着的为第一个数据字节,然后是一位应答位,后面继续第2个数据字节。 

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值