该协议是半双工 通信,含有上拉电阻。普通速率为100K/S,最大为400K/S,最大挂载2的七次方个设备。也就是128个。 起始信号:当时钟线为高的时候,数据线从高变低为起始信号 结束信号:时钟线为高,数据线从低到高为结束信号 开始发送信号时,前七个时钟脉冲传输的是数据,第8为对于主机来说(也就是 单片机)写或者读,0是读,1是写。 第九个为应答信号,低电平应答,高电平不应答 注意,电平时间宽度是有限制的,要大于3.7微妙,(us) At24c02,256字节。存储大小为256*8=2048,声音大小为2KB. 有一个读写保护脚,高电平时1的时候,只能被读,无法写。接地或者悬空,可以读写。 上电时,首先要检查是否存在AT24C02,可以用返回值来确定是否存在。iic就需要一个检测程序。 while(AT24CXX_Check()) 然后介绍的是AT24CXX_Check()函数 u8 AT24CXX_Check(void)
{
u8 temp;
temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
if(temp==0X55)return 0; 因为每次255地址里都是0x55,所以可以直接读取,是就返回值0 ,就结束循环
else//排除第一次初始化的情况
{
AT24CXX_WriteOneByte(255,0X55);
temp=AT24CXX_ReadOneByte(255);
if(temp==0X55)return 0;
}
return 1;
} 这个函数主要就是你往255地址里写一个数据,然后读取该数据,看能不能读到,可以就是存在,不可以就是不存在,当然,也可以把其他地址为当做标志。 这个里面有一个 AT24CXX_ReadOneByte(255);函数,就是读取地址字节的函数 u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
IIC_Start();
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();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
return temp;
}
这个主要的流程就是先发送器件地址,发送完了下一个是寄存器地址,然后进入接收模式,等待读取到的数据 就是IIC_Read_Byte(0); 函数 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;
} 这个例程里有一个不懂,就是SDA设置为输入的时候,是什么让SDA这个引脚发生电平变化的,这是读取一个字节的,有大神解答一下吗??????????????????????? 往一个地址里写一个数据函数 void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start();
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);
} 在开始信号和结束信号之间,就是发送器件地址,然后应答,然后发送器件寄存器地址,应答,然后写数据,应答,停止,即完成了一个数据往EEPROM里面写入。 读取一个字节,流程差不多 u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
IIC_Start();
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();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
return temp;
}
发送器件地址,产生应答,发送器件寄存器地址,产生应答,然后发送数据进入接收模式,等待应答完,就可以发送停止信号了。 我有一个不理解的就是读取eeprom芯片时,SDA被设置成了输入,它是怎么改变电平来传输数据的,还是说eeprom会驱动那个引脚,我感觉他不可以啊??????????
|