在上一篇文章仅仅介绍了单字节的写入和读取https://blog.csdn.net/Xiaomo_haa/article/details/87918394
现在介绍一下多字节操作。
E2PROM多字节操作
我们知道,写数据的时候,E2PROM是先写到缓冲区,然后再“搬运到”到掉电非易失区。所以这个过程需要一定的时间,AT24C02这个过程是不超过5ms!如果在这个时候去让它应答是没有响应的!
所以,当我们在写多个字节时,写入一个字节之后,再写入下一个字节之前,必须等待E2PROM再次相应才可以。
/*******************************************************************************
* 函数名 :E2Read
* 输入值 :unsigned char *buf, unsigned char addr, unsigned char led
* 返回值 :none
* 作者 :小默haa
* 时间 :2019年2月25日
* 功能描述:连续读取多个数据
* 备注 :buf为数据接收指针,addr为E2PROM中要读取的数据起始地址,len为读取长度
*******************************************************************************/
void E2Read(unsigned char *buf, unsigned char addr, unsigned char len)
{
do{ //用寻址操作查询当前是否可进行读写操作
IIC_Start();
IIC_SendByte(0xa0); //发送器件地址
if(IIC_WaitAck() == 1) //应答则跳出循环,非应答则进行下一次查询
break;
IIC_Stop();
}while(1);
IIC_SendByte(addr); //写入起始地址
IIC_WaitAck();
IIC_Stop();
IIC_Start(); //发送重复启动信号
IIC_SendByte(0xa1);
IIC_WaitAck();
IIC_SendByte((0x50 << 1) | 0x01); //寻址器件,后续为读操作
while(len > 1) //连续读取len-1个字节
{
*buf++ = IIC_RecByte(); //最后字节之前为读取操作并且应答
IIC_Ack(1);
len--;
}
*buf = IIC_RecByte(); //最后一个字节为读取操作并且非应答
IIC_Ack(0);
IIC_Stop();
}
/*******************************************************************************
* 函数名 :E2Write
* 输入值 :unsigned char *buf, unsigned char addr, unsigned char led
* 返回值 :none
* 作者 :小默haa
* 时间 :2019年2月25日
* 功能描述:连续写入多个数据
* 备注 :buf为源数据指针,addr为E2PROM中要写入的数据起始地址,len为写入长度
*******************************************************************************/
void E2Write(unsigned char *buf, unsigned char addr, unsigned char len)
{
while(len--)
{
do{ //用寻址操作查询当前是否可进行读写操作
IIC_Start();
if(IIC_WaitAck() == 1) //应答则跳出循环,非应答则进行下一次查询
break;
IIC_Stop();
}while(1);
}
IIC_SendByte(addr++); //写入起始地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(*buf++); //写入一个字节数据
IIC_WaitAck(); //等待从机应答
IIC_Stop(); //结束写操作,以等待写入完成
}
E2PROM的页写入
上面第三个我们也能感受到一次写一个字节的慢,然后等待ACK后才能写入下一个字节。效率太低!所以就诞生了分页写的模式。
这一次我们专门成立了一个eeprom的模块。
24C02,一共是 256 个字节,8 个字节一页,那么就一共有 32 页。
分配好页之后,如果我们在同一个页内连续写入几个字节后,最后再发送停止位的时序。EEPROM 检测到这个停止位后,就会一次性把这一页的数据写到非易失区域,就不需要像上节课那样写一个字节检测一次了,并且页写入的时间也不会超过 5ms。
如果我们写入的数据跨页了,那么写完了一页之后,我们要发送一个停止位,然后等待并且检测 EEPROM 的空闲模式,一直等到把上一页数据完全写到非易失区域后,再进行下一页的写入,这样就可以在很大程度上提高数据的写入效率。
/*******************************************************************************
* 函数名 :E2Write_page
* 输入值 :unsigned char *buf, unsigned char addr, unsigned char led
* 返回值 :none
* 作者 :小默haa
* 时间 :2019年2月25日
* 功能描述:连续写入一页数据
* 备注 :buf为源数据指针,addr为E2PROM中要写入的数据起始地址,len为写入长度
*******************************************************************************/
void E2Write_page(unsigned char *buf, unsigned char addr, unsigned char len)
{
while(len)
{
do{ //用寻址操作查询当前是否可进行读写操作
IIC_Start();
IIC_SendByte(0xa0);
if(IIC_WaitAck() == 1) //应答则跳出循环,非应答则进行下一次查询
break;
IIC_Stop();
}while(1);
IIC_SendByte(addr); //写入起始地址
IIC_WaitAck();
while(len > 0)
{
IIC_SendByte(*buf++); //写入一个字节数据
IIC_WaitAck();
len--; //待写入长度计数递减
addr++; //E2PROM地址递增
if((addr & 0x07) == 0) //检查地址是否到达页边界,24C02每页8字节
break; //到达页边界时,跳出循环,结束本次写操作
}
IIC_Stop();
}
}