通信协议——IIC协议

一. 什么是IIC协议

IIC(Inter-Integrated Circuit)协议是一种同步串行通信接口,它采用半双工工作模式,即在同一时间只能进行单向的数据传输。总线由两条信号线组成:一条是数据线SDA(Serial Data Line),用于传输数据;另一条是时钟线SCL(Serial Clock Line),由主设备提供时钟信号,以确保所有连接到总线的设备同步进行数据交换。

在I2C总线上,每个从设备都有一个唯一的地址,主设备通过发送这个地址来选择与其通信的目标设备。由于支持多主控功能,多个具备主控能力的设备可以在同一总线上竞争控制权,并通过硬件仲裁机制避免冲突。

由于其物理接口简单且占用线路少,I2C被广泛应用于嵌入式系统和电子设备中,方便连接各种低速外设,例如传感器、存储器、时钟芯片等。同时,I2C支持多种速度等级,能满足不同应用环境对数据传输速率的需求。

IIC总线结构:

① 由时钟线SCL和数据线SDA组成,并且都接上拉电阻,确保总线空闲状态为高电平

② 总线支持多设备连接,允许多主机存在,每个设备都有一个唯一的地址

③ 连接到总线上的数目受总线的最大电容400pf限制

④ 数据传输速率:标准模式100k bit/s  快速模式400k bit/s 高速模式3.4Mbit/s

二. IIC协议时序

起始信号(S):当SCL为高电平时,SDA从高电平变为低电平

停止信号(P):当SCL为高电平时,SDA从低电平变为高电平

应答信号:上拉电阻影响下SDA默认为高,而从机拉低SDA就是确认收到数据即ACK,否则NACK

2.1 起始信号的相应代码

//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us();
 	IIC_SDA=0;
	delay_us();
	IIC_SCL=0;    //钳住I2C总线,准备发送或接收数据 
}	

2.2 停止信号的相应代码

//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;
 	delay_us();
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us();							   	
}

2.3 应答信号的相应代码

u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us();//主机释放SDA线 
	IIC_SCL=1;delay_us();
	 
	while(READ_SDA)//SCL高电平读取SDA状态
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();//SDA高电平表示从机nack
			return 1;
		}
	}
	IIC_SCL=0;//SCL低电平表示结束ACK检查 
	return 0;  
} 

//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;//数据线为低电平,表示应答
	delay_us();
	IIC_SCL=1;
	delay_us();
	IIC_SCL=0;
}

//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;//数据线为高电平,表示非应答
	delay_us();
	IIC_SCL=1;
	delay_us();
	IIC_SCL=0;
}	

2.4 发送一字节数据的相应代码

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
		if((txd&0x80)>>7)//检测最高位是否为1
			IIC_SDA=1;
		else
			IIC_SDA=0;
		delay_us();   
		IIC_SCL=1;
		delay_us(); 
		IIC_SCL=0;	
		delay_us();
        txd<<=1; 	   //轮到次高位
    }
    IIC_SDA=1;    //发送完成,主机释放SDA线(应答信号)	 
} 	

2.5 读取一字节数据的相应代码

//读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();
		IIC_SCL=1;
        receive<<=1; //高位先输出,先收到的数据位要左移
        if(READ_SDA)receive++;//置1   
		delay_us(); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

三. AT24C02

3.1认识AT24C02

AT24C02是一款基于EEPROM技术的存储芯片,它拥有2K比特(即256字节)的存储容量。这款存储器采用I2C(Inter-Integrated Circuit)总线协议进行通信,通过I2C接口,主机可以对AT24C02进行读写操作,以保存和加载系统配置等信息,在系统上电时能够快速恢复到之前的状态,从而提高了系统的稳定性和灵活性。

EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,它的关键特性是在断电后仍能保持存储的数据不丢失。

AT24C02的原理图:

A0/1/2 : 设备地址决定引脚

WP  : 写保护引脚(接高电平只读,接地允许读和写)

SCL : 时钟线

SDA : 数据线

24C0232(page)组成且每页8Byte:

即可以通过字节(256byte)访问,也可以通过页访问。

3.2 AT24C02通讯地址

写操作地址:0xA0    读操作地址:0xA1

3.3 AT24C02的读写操作

3.3.1 写操作

AT24C02支持字节写模式页写模式。

字节写模式:一个地址一个数据进行写入。(支持这种)

页写模式:    连续写入数据。只需要写一个地址,连续写入数据时地址会自增,但存在页的限制,超出一页时,超出数据覆盖原先写入的数据。但读会自动翻页。(比如要写入9字节,8个字节已被写满,还剩1字节则会覆盖掉页头的数据)

AT24C02写时序

时序描述:

注意:

        EEPROM比较慢,必须等到10ms后再写下一个字节。

相关代码:

//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址    
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{			
	/*1.起始信号*/
    IIC_Start();  

	/*2.发送通信地址(写操作)*/
	IIC_Send_Byte(0XA0);
	
	/*3.等待应答型号*/
	IIC_Wait_Ack();	
	
	/*4.发送要写入的地址*/
    IIC_Send_Byte(WriteAddr);
	
	/*5.等待应答型号*/
	IIC_Wait_Ack();

	/*6.发送要写入的数据*/
	IIC_Send_Byte(DataToWrite);

	/*7.等待应答型号*/
	IIC_Wait_Ack();

	/*8.停止信号*/
    IIC_Stop();
	
	/*等待EEPROM写入完成,才可以写入下一字节*/
	delay_ms(10);	 
}


/*连续写操作*/
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
//pBuffer   :数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
	while(NumToWrite--)
	{
		AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
		WriteAddr++;
		pBuffer++;
	}
}

3.3.2 读操作

AT24C02支持当前地址读模式随机地址读模式顺序读模式

当前读模式:       基于上一次读/写操作的最后位置继续读出数据。

随机地址读模式:指定地址读出数据。(支持这种)

顺序读模式:       连续读出数据。

AT24C02读时序

时序描述:

//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值  :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{	
	u8 temp=0;
	
	/*1.起始信号*/
    IIC_Start();  

	/*2.发送通信地址(写操作)*/
	IIC_Send_Byte(0XA0);
	
	/*3.等待应答型号*/
	IIC_Wait_Ack();	
	
	/*4.发送要读取的地址*/
    IIC_Send_Byte(ReadAddr);
	
	/*5.等待应答型号*/
	IIC_Wait_Ack();
	
	/*6.起始信号*/
	IIC_Start();
	
	/*7.发送通信地址(读操作)*/
	IIC_Send_Byte(0XA1);
	
	/*8.等待应答型号*/
	IIC_Wait_Ack();

	/*9.读取数据,并发送非应答信号*/
	temp=IIC_Read_Byte(0);
	
	/*10.停止信号*/
	IIC_Stop();
    
	return temp;
}


/*连续读操作*/
//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer  :数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
	while(NumToRead)
	{
		*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);	
		NumToRead--;
	}
} 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值