接口/总线/驱动
现在我们已经实现了AT24C02的单字节读写,但是对于对于2K内存来说,如果对全部数据的读取或者写入都只用单字节读写来完成,这样就会很不方便。为了解决对大量数据的读写,现在介绍下AT24C02的页写和顺序读。
AT24C02器件按8字节/页执行页写。页写初始化与字节写相同,只是主器件不会在第一个数据后发送停止条件,而是在AT24C02的ACK以后,接着发送7个数据。AT24C02收到每个数据后都应答“0”。最后仍需由主器件发送停止条件,终止写序列。
//页写
void AT24C02_PageWrite(u8 wordAdd,u8 *str,u8 size,s8 *err)
{
u8 ack = 0;
u8 i = 0;
IIC_Start();
IIC_SendByte(AT24C02_ADD< < 1);//发器件地址
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -7;
return;
}
IIC_SendByte(wordAdd); //发字地址
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -8;
return;
}
for(i=0;i< size;i++)
{
IIC_SendByte(*str); //发字地址
str++;
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -9;
return;
}
}
IIC_Stop();
*err = 0;
}
接收到每个数据后,字地址的低3位或4位或5位内部自动加1,高位地址位不变,维持在当前页内。当内部产生的子地址达到该页边界地址时,随后的数据将写入该页的页首。为了解决这个问题,实现连续写的操作,下面介绍下连续写的方法。
连续写,首先要根据计算要写入首地址计算当前页剩多少字节可写,再判断要写的字节是否超过当前页可写字节数,如果不超过,直接调用页写函数写入即可;如果超过当前页可写字节数,则写完当前页,再依次页写剩余字节。
//连续写操作
void AT24C02_ContinueWrite(u8 wordAdd,u8 *str,u8 size,s8 *err)
{
u8 CanWriteBytes = 0;
while(1)
{
CanWriteBytes = 8 - wordAdd%8; //计算当前页可写字节
if(CanWriteBytes >= size)
{
AT24C02_PageWrite(wordAdd,str,size,err);
break;
}
else
{
AT24C02_PageWrite(wordAdd,str,CanWriteBytes,err);
wordAdd += CanWriteBytes;
str += CanWriteBytes;
size -= CanWriteBytes;
}
}
}
和连续写对应的是顺序读,顺序读可以通过“随机读”启动。主器件接收到一个数据后,应答ACK。只要AT24C02接收到ACK,将自动增加字地址并继续随时钟发送后面的数据。若达到存储器地址末尾,地址自动会转到0,仍可继续顺序读取数据。
主器件不应答“0”,而发送停止条件,即可结束顺序读操作。
void AT24C02_ContinueRead(u8 wordAdd,u8 *str,u8 size,s8 *err)
{
u8 ack = 0;
u8 i = 0;
IIC_Start();
IIC_SendByte(AT24C02_ADD< < 1);//发器件地址
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -10;
return;
}
IIC_SendByte(wordAdd); //发字地址
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -11;
return;
}
IIC_Start();
IIC_SendByte(AT24C02_ADD< < 1 | 1);//发器件地址(读)
ack = IIC_CheckAck();
if(ack != 0) //不应答
{
IIC_Stop();
*err = -12;
return;
}
for(i = 0;i< size-1;i++)
{
*str++ = IIC_ReadByte();
IIC_AcktoSlave();
}
*str = IIC_ReadByte();
IIC_NoAcktoSlave();
IIC_Stop();
*err = 0;
}
最后,在主文件中调用连续写和顺序读两个函数。将程序烧入开发板中,打开串口助手,读出的数据和写入的完全一样,连续写和顺序读就成功了。AT24C02就介绍到这里,感兴趣的还可以自己拓展下,用AT24C02尝试下其他小项目。
#include "stm32f4xx.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"
#include "AT24C02.h"
u8 str[40]="hello world!rnhello world!rn";
u8 buf[40]={0};
int main()
{
s8 err = 0;
Usart1_Init(115200);
LED_Init(); //初始化LED灯
AT24C02_Init();
AT24C02_ContinueWrite(6,str,sizeof(str),&err);
AT24C02_ContinueRead(6,buf,sizeof(str),&err);
printf("buf = %srn",buf);
while(1)
{
}
}
全部0条评论
快来发表一下你的评论吧 !