I2C接口的EEPROM芯片有AT25C02,AT25C04,AT25C08,AT24C16等。
先来看看读写时序
void EEPROM_WriteChar(uint16_t addr, uint8_t dat)
{
I2C_Start();
I2C_WriteChar(0xA0);
I2C_Ack();
//I2C_WriteChar(addr>>8);
//I2C_Ack();
I2C_WriteChar(addr&0xff);
I2C_Ack();
I2C_WriteChar(dat);
I2C_Ack();
I2C_Stop();
}
int EEPROM_PageWrite(uint16_t addr, uint8_t *dat, uint8_t len)
{
uint8_t i;
uint8_t ack;;
int ret;
ack = 0;
I2C_Start();
I2C_WriteChar(0xA0);
ack |= I2C_Ack();
//I2C_WriteChar(addr>>8);
//ack |= I2C_Ack();
I2C_WriteChar(addr&0xff);
ack |= I2C_Ack();
for (i=0; i<len; i++)
{
I2C_WriteChar(*dat);
dat++;
ack |= I2C_Ack();
}
I2C_Stop();
if (ack == 0) ret = 0;
else ret = -1;
return ret;
}
int EEPROM_WriteChars(uint16_t addr, uint8_t *dat, uint8_t len)
{
uint8_t i;
uint8_t page;
uint8_t page_size;
uint8_t offset;
int ret;
page_size = 16;
page = len / page_size;
for (i=0; i<page; i++)
{
offset = i * page_size;
EEPROM_PageWrite(addr+offset, dat+offset, page_size);
}
page_size = len % page_size;
if (page_size != 0)
{
offset = i * page_size;
EEPROM_PageWrite(addr+offset, dat+offset, page_size);
}
}
uint8_t EEPROM_ReadChar(uint16_t addr)
{
uint8_t read_data;
I2C_Start();
I2C_WriteChar(0xA0);
I2C_Ack();
//I2C_WriteChar(addr>>8);
//I2C_Ack();
I2C_WriteChar(addr&0xff);
I2C_Ack();
I2C_Stop();
I2C_Start();
I2C_WriteChar(0xA1);
I2C_Ack();
read_data = I2C_ReadChar();
I2C_NAck();
I2C_Stop();
return read_data;
}
int EEPROM_ReadChars(uint16_t addr, uint8_t *dat, uint8_t len)
{
int ret = 0;
uint8_t i;
uint8_t ack;
ack = 0;
I2C_Start();
I2C_WriteChar(0xA0);
ack |= I2C_Ack();
//I2C_WriteChar(addr>>8);
//ack |= I2C_Ack();
I2C_WriteChar(addr&0xff);
ack |= I2C_Ack();
I2C_Stop();
I2C_Start();
I2C_WriteChar(0xA1);
ack |= I2C_Ack();
for (i=0; i<len; i++)
{
dat[i] = I2C_ReadChar();
I2C_SendAck();
}
ack |= I2C_NAck();
I2C_Stop();
if (ack == 0) ret =0;
else ret = -1;
return ret;
}
调试时去连续读取数据时,读取失败,原因是I2C_ReadChar()之后,需要主机发送ACK,而不是等待从机发送的ACK。修改之后,可以连续读取数据了。