一家只做t恤的网站,阜阳恒亮做网站多少钱,青岛企业建设网站企业,咸阳做网站托管IIC通信协议
IIC是同步半双工通信#xff0c;一个数据线SDA和一个时钟SCL线#xff0c;可以接受和发送数据。在CPU与被控IC之间、IC与IC之间进行双向传送。
空闲状态
IIC总线的SDA和SCL两条信号线同时处于高电平时#xff0c;规定为总线的空闲状态。
起始信号
当SCL为高…IIC通信协议
IIC是同步半双工通信一个数据线SDA和一个时钟SCL线可以接受和发送数据。在CPU与被控IC之间、IC与IC之间进行双向传送。
空闲状态
IIC总线的SDA和SCL两条信号线同时处于高电平时规定为总线的空闲状态。
起始信号
当SCL为高期间SDA由高到低的跳转 代码实现为
//产生IIC起始信号
void IIC_Start(void)
{SDA_OUT(); //sda线输出模式IIC_SDA1; IIC_SCL1;delay_us(4);IIC_SDA0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL0;//钳住I2C总线准备发送或接收数据
} 停止信号
当SCL为高期间SDA由低到高的跳转 代码实现
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL0;IIC_SDA0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL1; delay_us(4); IIC_SDA1;//发送I2C总线结束信号
}应答信号
发送器每发送一个字节就在时钟脉冲9期间释放数据线由接收器反馈一个应答信号。应答信号为低电平时规定为有效应答位表示接收器已经成功接收到了该字节。应答信号为高电平时规定为非应答位一般表示接收器接收该字节没有成功。 对于反馈有效应答位ACK的要求是接收器第9个时钟脉冲之前的低电平将SDA线拉低并且确保在该时钟的高电平期间为稳定的低电压。 代码实现为
//产生ACK应答
void IIC_Ack(void)
{IIC_SCL0;SDA_OUT();IIC_SDA0;delay_us(2);IIC_SCL1;delay_us(2);IIC_SCL0;
}//不产生ACK应答
void IIC_NAck(void)
{IIC_SCL0;SDA_OUT();IIC_SDA1;delay_us(2);IIC_SCL1;delay_us(2);IIC_SCL0;
}
//等待应答信号到来
//返回值1接收应答失败
// 0接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime0;SDA_IN(); //SDA设置为输入 IIC_SDA1;delay_us(1); IIC_SCL1;delay_us(1); while(READ_SDA){ucErrTime;if(ucErrTime250){IIC_Stop();return 1;}}IIC_SCL0;//时钟输出0 return 0;
} 数据的有效性
IIC总线进行数据传送时时钟信号为高电平期间数据线上的数据必须保持稳定只有在时钟线上的信号为低电平期间数据线上的高电平或低电平才允许变化。即数据在SCL的上升沿到来之前就需要准备好并且在下降沿到来之前必须保持稳定。
数据的传送
在IIC总线上传送的每一位数据都有一个时钟脉冲相对应同步控制即在SCL串行时钟的配合下在SDA上逐位串行传送每一位数据数据位的传输是边沿触发。
发送一字节代码实现为
//IIC发送一个字节
//返回从机有无应答
//1有应答
//0无应答
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL0;//拉低时钟开始数据传输for(t0;t8;t){ IIC_SDA(txd0x80)7;txd1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL1;delay_us(2); IIC_SCL0; delay_us(2);}
} 数据传输之前IIC_SCL必须等于0即时信号为低电平然后准备一位数据准备好之后IIC_SCL1即时钟信号为高电平数据就传输过去了 对于下面的代码
IIC_SDA(txd0x80)7;
txd1;无符号类型左移丢弃最高位低位补0无符号类型右移丢弃最低位低位补0txd0x80让txd第8位数据不变其他为变成0txd的值不受影响左移7位将最高位的数据赋值给IIC_SDA当IIC_SCL1时第八位数据就传输过去了txd1让第7位数据变成第8位数据下次循环就传输原来第7位数据了。循环8次将一字节数据传输完毕。
读取数据代码实现
//读1个字节ack1时发送ACKack0发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive0;SDA_IN();//SDA设置为输入for(i0;i8;i ){IIC_SCL0; delay_us(2);IIC_SCL1;receive1;if(READ_SDA)receive; delay_us(1); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}对于下面的代码 receive1;if(READ_SDA)receive; READ_SDA是获取SDA线上的电压高电压说明说明传送过来的数据是1receive下一次的时候 receive1receive先右移一位然后接受数据这样循环8次就能保证接受的数据在原来的位置上了。
与EEPROM通信
硬件连接 EEPROM是一种掉电后数据不丢失的存储芯片可以在电脑上或专用设备上擦除已有信息重新编程。 24C02的总容量是256个字节接口是IIC
模式选择
硬件连接中A2A1A00接地所以我们读数据时只需写入0xA1表示读模式写数据时只需写入0xA0表示写模式
写时序
下面是写入一个字节数据的过程
一个IIC_START信号写入模式写入0xA0等待一个ACK发送写入数据的地址(0~255等待一个ACK发送一个字节等待一个ACK一个STOP信号 具体代码如下
//在AT24CXX指定地址写入一个数据
//WriteAddr :写入数据的目的地址
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{ IIC_Start(); if(EE_TYPEAT24C16){IIC_Send_Byte(0XA0); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(WriteAddr8);//发送高地址 }else IIC_Send_Byte(0XA0((WriteAddr/256)1)); //发送器件地址0XA0,写数据 IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr%256); //发送低地址IIC_Wait_Ack(); IIC_Send_Byte(DataToWrite); //发送字节 IIC_Wait_Ack(); IIC_Stop();//产生一个停止条件 delay_ms(10);
}读数据
下面是读一个字节数据的过程
产生一个START信号写入0xA0表示是写模式等待一个ACK写入读数据的地址等待一个ACK产生一个START信号写入0xA1表示是读模式等待一个ACK读取数据 实现代码如下
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址
//返回值 :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{ u8 temp0; IIC_Start(); if(EE_TYPEAT24C16){IIC_Send_Byte(0XA0); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(ReadAddr8);//发送高地址 }else IIC_Send_Byte(0XA0((ReadAddr/256)1)); //发送器件地址0XA0,写数据 IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr%256); //发送低地址IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0XA1); //进入接收模式 IIC_Wait_Ack(); tempIIC_Read_Byte(0); IIC_Stop();//产生一个停止条件 return temp;
}