51单片机中的EEPROM怎么用?

EEPROM (Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。一般用在即插即用。

EEPROM模块在“蓝桥杯”单片机设计与开发项目比赛中经常出现,其在决赛中必然出现,在近四年中省赛出现过一次。可以说EEPROM的掌握是准备“蓝桥杯”单片机设计与开发比赛避不开的内容。

蓝桥杯单片机开发所使用的EEPROM储存芯片是AT24C02,通过IIC数据总线进行数据传输。通过一根SCL时钟信号线和SDA数据信号线串行传输。
在这里插入图片描述
引脚说明:
A0,A1,A2:硬件地址引脚。
WP:写保护引脚,接高电平只读,接地允许读和写。
SCL和SDA:IIC总线。

先把EEPROM和IIC的模块代码放出来

IIC.c

#include "reg52.h"
#include "intrins.h"
#include "I2C.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}
//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

void operate_delay(unsigned char t)
{
	unsigned i;
	while(t--)
		for(i=0;i<112;i++);
}
void write_eeprom(unsigned char add,unsigned char val)
{
	IIC_Start();
	IIC_SendByte(0xA0);//器件地址
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(val);
	IIC_WaitAck();
	IIC_Stop();
	operate_delay(10);
}

unsigned char read_eeprom(unsigned char add)
{
	unsigned char da;
	
	IIC_Start();
	IIC_SendByte(0xA0);//器件地址
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xA1);//读取地址
	IIC_WaitAck();
	da = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return da;
}


代码中涉及到IIC通信协议的都会在比赛时由官方提供,我们也不是主要讲IIC通信协议的。这里就讲讲利用IIC与AT24C02通信的两个函数加一个操作延时函数。

void operate_delay(unsigned char t)
{
	unsigned i;
	while(t--)
		for(i=0;i<112;i++);
}

这里首先重点提一下,AT24C02对时序要求较高,如果操作延时函数未延时到足够的时间,可能会导致写入失败或部分写入的情况。

EEPROM写数据

在这里插入图片描述
操作时序:
启动总线-----发送设备地址+写-----等待应答-----发送数据的储存地址(0x00-0xFF,256个字节)-----等待应答-----发送数据-----等待应答-----停止总线

注意:

在写数据的过程中,每成功写入一个字节,E2PROM存储空间的地址就会自动加1,当加到0xFF后,再写一个字节,地址就会溢出又变成0x00。

写数据的时候需要注意,E2PROM是先写到缓冲区,然后再“搬运到”到掉电非易失区。所以这个过程需要一定的时间,AT24C02这个过程是不超过5ms!如果在这个时候去让它应答是没有响应的!

所以,当我们在写多个字节时,写入一个字节之后,再写入下一个字节之前,必须等待E2PROM再次相应才可以。

但是当我们单字节写数据时,不用考虑得不到应答的问题,直接停止总线即可。

void write_eeprom(unsigned char add,unsigned char val)
{
	IIC_Start();
	IIC_SendByte(0xA0);//器件地址
	IIC_WaitAck();
	IIC_SendByte(add);//写入地址
	IIC_WaitAck();
	IIC_SendByte(val);//写入值
	IIC_WaitAck();
	IIC_Stop();
	operate_delay(10);
}

EEPROM读数据

在这里插入图片描述
操作时序:
启动总线——发送设备地址——等待应答——发送数据储存地址+写——等待应答——发送设备地址+读——等待应答——读取数据——主机发送是否应答。

注意:

读取数据时一定要要等待应答

unsigned char read_eeprom(unsigned char add)
{
	unsigned char da;
	
	IIC_Start();
	IIC_SendByte(0xA0);//器件地址
	IIC_WaitAck();
	IIC_SendByte(add);//写入地址
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xA1);//读取地址
	IIC_WaitAck();
	da = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return da;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盒子桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值