从图中可以看到,如果进行一个写的操作,也是要先发送一个启动操作,然后发送设备地址,接着发送字节地址,最后发送数据,然后停止。Tips:先发送高位,再发送低位
设备地址(Device Address):IIC总线上的地址。
A2,A1,A0看设备接线的电平,若A1接低电平,则为0;
第八位(R/W)为0时,为写操作;第八位为1时,为读操作。
接下来的代码中,Device Address设为0xA0;
发送字节代码
void IIC_Send_Byte(unsigned char data)
{
SDA_OUT();
for(int i=0;i<8;i++)
{
if(data & 0x80)
{
IIC_SDA_H;
}
else
{
IIC_SDA_L;
}
IIC_SCL_L;
IIC_SCL_H;
IIC_SCL_L;
data=data<<1;
}
}
写单个字节代码
可以看一下第一个图,一一对应代码,就简单易懂了。
void IIC_Write_Byte(unsigned int addr,unsigned char data)
{
IIC_START();
IIC_Send_Byte(0xA0);
while(IIC_Wait_ACK());
IIC_Send_Byte(addr);
while(IIC_Wait_ACK());
IIC_Send_Byte(data);
while(IIC_Wait_ACK());
IIC_STOP();
}
写多个字节代码
这里假设发送size个字节
void IIC_Write_Page(unsigned int addr,unsigned char *data,unsigned int size)
{
IIC_START();
IIC_Send_Byte(0xA0);
while(IIC_Wait_ACK());
IIC_Send_Byte(addr);
while(IIC_Wait_ACK());
while(size--)
{
IIC_Send_Byte(*data);
while(IIC_Wait_ACK());
data++;
addr++;
}
IIC_STOP();
}
写任意长度字节
void AT24C02_Wirte(unsigned char addr,unsigned char *data,unsigned int size)
{
while(size--)
{
IIC_Write_Byte(addr,*data);
data++;
addr++;
}
}
读当前地址的字节代码
unsigned char IIC_Receive_Byte(void)
{
unsigned int i;
unsigned char data;
SDA_IN();
for(i = 0; i < 8; i++)
{
IIC_SCL_L;
IIC_SCL_H;
data <<= 1;
if(Read_SDA)
data++;
IIC_SCL_L;
}
return data;
}
随机读代码(读出特定地址的值)
unsigned char IIC_Read_Byte(unsigned char addr)
{
unsigned char data;
//假写beginning
IIC_START();
IIC_Send_Byte(0xA0);
while(IIC_Wait_ACK());
IIC_Send_Byte(addr);
while(IIC_Wait_ACK());
//假写end
IIC_START();
IIC_Send_Byte(0xA1);
while(IIC_Wait_ACK());
data = IIC_Receive_Byte();
IIC_STOP();
return data;
}
顺序读代码
void AT24C02_Read_Buf(unsigned char addr, unsigned char *data, unsigned int size)
{
//假写beginning
IIC_START();
IIC_Send_Byte(0xA0);
while(IIC_Wait_ACK());
IIC_Send_Byte(addr);
while(IIC_Wait_ACK());
//假写end
IIC_START();
IIC_Send_Byte(0xA1);
while(IIC_Wait_ACK());
while(size > 1)
{
*data = IIC_Receive_Byte();
IIC_ACK();
data++;
addr++;
size--;
}
*data = IIC_Receive_Byte();
IIC_STOP();
}