一、前言
1.1 功能介绍
在嵌入式系统设计中,数据的存储与读取是至关重要的一环。随着技术的不断发展,对存储设备的性能、容量和可靠性要求也越来越高。EEPROM(电可擦除可编程只读存储器)作为一种非易失性存储介质,以其数据存储可靠、功耗低、读取速度快等特点,广泛应用于各种嵌入式系统中。本项目在利用STC90C51单片机和EEPROM-AT24C02存储器芯片实现高效的数据读写存储功能,以满足现代嵌入式系统对数据存储的需求。
本项目的主要目标是通过STC90C51单片机与EEPROM-AT24C02存储器芯片的配合使用,实现以下功能:
- 数据写入:通过STC90C51单片机向EEPROM-AT24C02存储器芯片中写入数据,实现数据的非易失性存储。EEPROM-AT24C02存储容量为2Kbit(即256字节),足够满足大多数嵌入式系统对数据存储的需求。
- 数据读取:STC90C51单片机能够从EEPROM-AT24C02存储器芯片中读取已存储的数据,并在需要时进行处理或使用。由于EEPROM-AT24C02的读取速度快,能够保证数据访问的高效性。
1.2 AT24C02介绍
AT24C02是一款串行EEPROM(电可擦除可编程只读存储器)芯片,由CATALYST公司(或Atmel公司,因品牌收购关系)生产,广泛应用于各种电子设备中,特别是那些需要数据存储和参数保存的场景。
以下是关于AT24C02的详细介绍:
主要技术参数
- 存储容量:2Kbit(256个8位字节),适合存储少量但重要的数据。
- 工作电压范围:1.8V至5.5V,宽电压范围使得AT24C02能够适应不同的电源供电情况。
- 通信接口:I2C串行总线接口,通过两根总线(串行数据线SDA和串行时钟线SCL)与微处理器或其他设备进行通信。
- 存储速率:可达400KHz,提供较快的数据传输速度。
- 可擦写次数:高达100万次,确保长期使用的可靠性。
- 存储器保持时间:至少10年,保证数据长时间存储的稳定性。
- 工作温度范围:虽然不同资料给出的温度范围略有差异,但一般可认为是-40℃至+85℃或-55℃至+125℃,适应各种工作环境。
主要特点
- 低功耗:采用先进的CMOS技术,功耗极低,适用于电池供电等低功耗应用场景。
- 高可靠性:内部具有校验和功能,可以检测和纠正数据传输中的错误,提高数据传输的可靠性。
- 多种封装形式:提供DIP、SOP、TSSOP等多种封装形式,方便用户根据实际需求选择。
- 易于使用:通过I2C总线接口与微处理器进行通信,简化了与主机的连接和数据传输过程。
应用领域
AT24C02广泛应用于各种需要数据存储和参数保存的领域:
- 工业控制:用于存储和读取PLC程序、传感器数据等。
- 仪器仪表:用于存储电子秤、温度计、压力计等设备的校准参数。
- 网络通信:用于存储MAC地址、序列号等数据。
- 汽车电子:用于存储汽车门锁控制、气囊控制等信息。
二、代码实现
2.1 main.c
#include <reg51.h>
#include "delay.h"
#include "key.h"
#include "type.h"
#include "led.h"
#include "uart.h"
#include "timer.h"
#include "exti.h"
#include "infrared.h"
#include "ds18b20.h"
#include "at24c02.h"
//u8 at24c02_w[8]="1234567";
//u8 at24c02_r[8];
int main()
{
u8 dat;
UART_Init(); //初始化串口波特率为4800
while(1)
{
//单个字节读写测试
AT24C02_WriteOneByte(5,0xAA);
dat=AT24C02_ReadOneByte(5);
printf("dat=%d\r\n",(int)dat);
//多个字节读写测试
// AT24C02_WriteByte(0,8,at24c02_w);
// AT24C02_ReadByte(0,8,at24c02_r);
// printf("at24c02_r=%s\r\n",at24c02_r);
DelayMs(1000);
}
}
2.2 AT24C02.c
#include "at24c02.h"
#include "iic.h"
/*
函数功能: 写一个字节
函数参数:
u8 addr 数据的位置(0~255)
u8 dat 数据范围(0~255)
*/
void AT24C02_WriteOneByte(u16 addr,u8 dat)
{
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
IIC_GetAck();//获取应答
IIC_SendOneByte(addr); //数据存放的地址
IIC_GetAck();//获取应答
IIC_SendOneByte(dat); //发送将要存放的数据
IIC_GetAck();//获取应答
IIC_SendStop(); //停止信号
DelayMs(10); //等待写
}
/*
函数功能: 读一个字节
函数参数:
u8 addr 数据的位置(0~255)
返回值: 读到的数据
*/
u8 AT24C02_ReadOneByte(u16 addr)
{
u8 dat=0;
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
IIC_GetAck();//获取应答
IIC_SendOneByte(addr); //将要读取数据的地址
IIC_GetAck();//获取应答
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_READ_ADDR);//发送设备地址
IIC_GetAck();//获取应答
dat=IIC_RecvOneByte();//读取数据
IIC_SendAck(1); //发送非应答
IIC_SendStop(); //停止信号
return dat;
}
/*
函数功能: 从指定位置读取指定长度的数据
函数参数:
u16 addr 数据的位置(0~255)
u16 len 读取的长度
u8 *buffer 存放读取的数据
返回值: 读到的数据
*/
void AT24C02_ReadByte(u16 addr,u16 len,u8 *buffer)
{
u16 i=0;
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
IIC_GetAck();//获取应答
IIC_SendOneByte(addr); //将要读取数据的地址
IIC_GetAck();//获取应答
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_READ_ADDR);//发送设备地址
IIC_GetAck();//获取应答
for(i=0;i<len;i++)
{
buffer[i]=IIC_RecvOneByte();//读取数据
if(i<len-1)IIC_SendAck(0); //发送应答
else IIC_SendAck(1); //发送非应答
}
IIC_SendStop(); //停止信号
}
/*
函数功能: AT24C02页写函数
函数参数:
u16 addr 写入的位置(0~1023)
u8 len 写入的长度(每页16字节)
u8 *buffer 存放读取的数据
*/
void AT24C02_PageWrite(u16 addr,u16 len,u8 *buffer)
{
u16 i=0;
IIC_SendStart();//起始信号
IIC_SendOneByte(AT24C02_WRITE_ADDR);//发送设备地址
IIC_GetAck();//获取应答
IIC_SendOneByte(addr); //数据存放的地址
IIC_GetAck();//获取应答
for(i=0;i<len;i++)
{
IIC_SendOneByte(buffer[i]); //发送将要存放的数据
IIC_GetAck();//获取应答
}
IIC_SendStop(); //停止信号
DelayMs(10); //等待写
}
/*
函数功能: 从指定位置写入指定长度的数据
函数参数:
u16 addr 数据的位置(0~255)
u16 len 写入的长度
u8 *buffer 存放即将写入的数据
返回值: 读到的数据
*/
void AT24C02_WriteByte(u16 addr,u16 len,u8 *buffer)
{
u8 page_byte=8-addr%8; //得到当前页剩余的字节数量
if(page_byte>len) //判断当前页剩余的字节空间是否够写
{
page_byte=len; //表示一次性可以写完
}
while(1)
{
AT24C02_PageWrite(addr,page_byte,buffer); //写一页
if(page_byte==len)break; //写完了
buffer+=page_byte; //指针偏移
addr+=page_byte;//地址偏移
len-=page_byte;//得到剩余没有写完的长度
if(len>8)page_byte=8;
else page_byte=len; //一次可以写完
}
}
2.3 AT24C02.h
#ifndef _AT24C02_H_
#define _AT24C02_H_
#include <reg51.h>
#include "delay.h"
#include "type.h"
//地址
#define AT24C02_WRITE_ADDR 0xA0
#define AT24C02_READ_ADDR 0xA1
//函数声明
void AT24C02_WriteOneByte(u16 addr,u8 dat);
u8 AT24C02_ReadOneByte(u16 addr);
void AT24C02_WriteByte(u16 addr,u16 len,u8 *buffer);
void AT24C02_PageWrite(u16 addr,u16 len,u8 *buffer);
void AT24C02_ReadByte(u16 addr,u16 len,u8 *buffer);
#endif