一、引脚说明
WP:当该引脚接GND时可读可写,接Vcc只读。
二、器件地址
开发板原理图:
所以器件写地址为0xA0,读地址为0xA1。
三、写操作
void AT24C02_ByteWrite(uint8_t addr,uint8_t data)
{
IIC_Start();
IIC_Write_Byte(dev_addr | write_bit);
IIC_Wait_Ack();
IIC_Write_Byte(addr);
IIC_Wait_Ack();
IIC_Write_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
Delay_ms(5);
}
一定要在末尾延时一段时间,不然无法读取成功。 原因如下
延时最大5ms,所以代码最后延时了5ms。
void Page_Write(uint8_t addr,uint8_t * data,uint8_t size)
{
uint8_t i;
IIC_Start();
IIC_Write_Byte(dev_addr | write_bit);
IIC_Wait_Ack();
IIC_Write_Byte(addr);
IIC_Wait_Ack();
for(i=0;i<size;i++)
{
IIC_Write_Byte(*(data++));
IIC_Wait_Ack();
}
IIC_Stop();
Delay_ms(5);
}
四、读操作
读取当前地址的下一位字节数据
内部数据字地址计数器保持在上一次读或写操作期间访问的最后一个地址。每读取一个字节,地址就自动加1.所以读取的内容是上一次地址的+1的数据。
uint8_t CurAddr_Read(void){uint8_t data;
IIC_Start();
IIC_Write_Byte( dev_addr | read_bit );
IIC_Wait_Ack();
data = IIC_Byte_Read();
IIC_No_Ack();
IIC_Stop();
return data;
}
测试代码如下
AT24C02_ByteWrite(0x02,7);
AT24C02_ByteWrite(0x01,6);
printf("%x", CurAddr_Read());
-------------------------------------------------------分割线---------------------------------------------------
指定地址读取字节数据
uint8_t Ran_Read(uint8_t addr)
{
uint8_t data;
IIC_Start();
IIC_Write_Byte(dev_addr | write_bit);
IIC_Wait_Ack();
IIC_Write_Byte(addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Write_Byte( dev_addr | read_bit );
IIC_Wait_Ack();
data = IIC_Byte_Read();
IIC_No_Ack();
IIC_Stop();
return data;
}
测试代码如下:
AT24C02_ByteWrite(0x02,7);
AT24C02_ByteWrite(0x01,6);
printf("%x", Ran_Read(0x01));
连续读:
void Seq_Read(uint8_t addr,uint8_t *data,uint8_t size)
{
uint8_t i;
IIC_Start();
IIC_Write_Byte(dev_addr | write_bit);
IIC_Wait_Ack();
IIC_Write_Byte(addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Write_Byte( dev_addr | read_bit );
IIC_Wait_Ack();
for(i=0;i<size;i++)
{
(*data) = IIC_Byte_Read();
data ++;
IIC_Ack();
}
IIC_No_Ack();
IIC_Stop();
}
效果如图:
测试代码
uint8_t data[] = {5,4,5,2,1};
uint8_t read[5]={0};
Page_Write(0x00,data,sizeof(data));
Seq_Read(0x00,read,sizeof(data));
for(i=0;i<sizeof(data);i++)
{
printf("%x\n", read[i]);
}