AT24C02 EEPROM芯片详解:硬件特性、IIC协议及读写操作
AT24C02 EEPROM芯片详解:硬件特性、IIC协议及读写操作
在单片机开发中,断电数据保存是一个常见的需求。例如,智能家居设备的用户设置、电子秤的校准参数等都需要在断电后仍能保留。AT24C02作为一款IIC接口的EEPROM芯片,具备非易失性存储、容量适中、接口简单等优势,非常适合用于这类场景。本文将详细介绍AT24C02的硬件特性、IIC协议的核心原理以及具体的读写操作方法。
1.为什么需要EEPROM?
在单片机开发中,断电数据保存是常见的需求。例如,智能家居设备的用户设置、电子秤的校准参数等都需要在断电后仍能保留。AT24C02作为一款IIC接口的EEPROM芯片,具备以下优势:
- 非易失性存储:断电后数据不丢失。
- 容量适中:256字节(2Kb),适合存储小规模数据。
- 接口简单:仅需两根信号线(SDA、SCL),节省单片机IO口资源。
2.AT24C02硬件解析
1.芯片特性
- 工作原理:2.7V~5.5V(兼容51单片机5V供电)。
- 存储结构:分32页,每页八字节,支持页写入模式。
- 器件地址:高4位固定为1010,低四位由A0~A2引脚电平决定(默认接地地址为0xA0)。
2.硬件连接
3.IIC协议核心原理
IIC协议通过时序信号实现数据传输,需掌握以下关键操作:
1.起始信号与停止信号
在通信里,SCL 线高电平时,SDA 线从高到低是起始信号,从低到高是终止信号,都由主机发。起始信号一出现,总线被占用;终止信号发出后,总线恢复空闲。
void I2C_Start(void)
{
I2C_SDA=1;
I2C_SCL=1;
I2C_SDA=0;
I2C_SCL=0;
}
void I2C_Stop(void)
{
I2C_SDA=0;
I2C_SCL=1;
I2C_SDA=1;
}
2.数据有效性规定
I2C 总线传输数据时,时钟信号高电平时,数据线数据要保持稳定,仅时钟信号低电平时,数据线电平状态才可改变。每次数据传输以字节为单位,且传输的字节数量不设上限。
void I2C_SendByte(unsigned char Byte)
{
unsigned char i;
for (i=0;i<8;i++)
{
I2C_SDA=Byte&(0x80>>i);
I2C_SCL=1;
I2C_SCL=0;
}
}
unsigned char I2C_ReceiveByte(void)
{
unsigned char i,Byte=0x00;
I2C_SDA=1;
for(i=0;i<8;i++)
{
I2C_SCL=1;
if(I2C_SDA){Byte|=(0x80>>i);}
I2C_SCL=0;
}
return Byte;
}
3.应答响应
I2C 总线数据传输时,发送器件传完一字节数据后,需紧跟校验位。此校验位由接收端控制 SDA 实现,是传输响应,分“应答(ACK)”和“非应答(NACK)”。 接收端收到字节数据或地址后,想继续接收就发“应答(ACK)”低电平脉冲,发送方继续发数据;想结束则发“非应答(NACK)”高电平脉冲,发送方产生停止信号。 每个字节 8 位,先传最高位,后随一位应答位,一帧共 9 位。若从机不对寻址信号应答,将数据线置高,主机发终止信号。从机接收中无法继续,通过“非应答”通知主机结束。主机接收完最后一字节,用“非应答”结束,从机释放 SDA 线。起始信号必需,结束和应答信号可选。
void I2C_SendAct(bit ActBit)
{
I2C_SDA=ActBit;
I2C_SCL=1;
I2C_SCL=0;
}
unsigned char I2C_ReceiveAct(void)
{
unsigned char ActBit;
I2C_SDA=1;
I2C_SCL=1;
ActBit=I2C_SDA;
I2C_SCL=0;
return ActBit;
}
4.总线的寻址方式
4.AT24C02介绍
AT24C02器件地址为7位,高四位固定为1010,低3位由A0/A1/A2信号的电平决定。因为传输地址或数据是以字节为单位传送的,当传送地址时,器件地址占7位,还有最后一位(最低位R/W)用来选择读写方向,它与地址无关。其格式如下:
#define AT24C02_ADDRESS 0xA0
本开发板已经将A0/A1/A2连接到GND,所以器件地址为1010000,即0x50(未计算最低位)。如果要对芯片进行写操作时,R/W即为0,写器件地址即为0xA0;如果要对芯片进行读操作时,R/W即为1,此时读器件地址为0xA1。开发板上也将WP引脚直接接在GND上,此时芯片允许数据正常读写。
IIC总线时序如下:
1.写入一个字节
// 向AT24C02指定地址写入一个字节
void AT24C02_WriteByte(unsigned char WordAddress, unsigned char Data) {
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS);
if (I2C_ReceiveAct()) {
// 应答错误处理,可根据需求添加更多逻辑
return;
}
I2C_SendByte(WordAddress);
if (I2C_ReceiveAct()) {
return;
}
I2C_SendByte(Data);
if (I2C_ReceiveAct()) {
return;
}
I2C_Stop();
}
- 启动 I2C 通信 (
I2C_Start()
):通过
I2C_Start
函数产生 I2C 起始信号,标志着一次新的 I2C 通信开始。 - 发送设备地址 (
I2C_SendByte(AT24C02_ADDRESS)
):将 AT24C02 的设备地址发送到总线上。
AT24C02_ADDRESS
是 AT24C02 的 7 位设备地址加上读写位(写操作时读写位为 0)。发送完设备地址后,调用
I2C_ReceiveAct
函数检查 AT24C02 是否返回了应答信号。如果没有收到应答信号,说明通信可能出现问题,函数直接返回。 - 发送存储地址 (
I2C_SendByte(WordAddress)
):将想要写入数据的存储地址发送到总线上。同样,发送完后检查 AT24C02 的应答信号。 - 发送要写入的数据 (
I2C_SendByte(Data)
):将需要写入到 AT24C02 中的数据发送到总线上,然后再次检查应答信号。 - 停止 I2C 通信 (
I2C_Stop()
):通过
I2C_Stop
函数产生 I2C 停止信号,结束本次通信。
2.读取一个字节
unsigned char AT24C02_ReadByte(unsigned char WordAddress) {
unsigned char Data;
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS);
if (I2C_ReceiveAct()) {
return 0; // 应答错误,返回0
}
I2C_SendByte(WordAddress);
if (I2C_ReceiveAct()) {
return 0;
}
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS | 0x01);
if (I2C_ReceiveAct()) {
return 0;
}
Data = I2C_ReceiveByte();
I2C_SendAct(1); // 发送非应答位
I2C_Stop();
return Data;
}