at24c256与at24c02的区别在于以2个字节来控制地址 其中首字节最高位忽略,其余7位和下一字节的高2位 构成9位的页地址,共512页,低字节的剩余6位为页内地址,共64BYTE。 另外要注意的是整片写数据时在翻页时需要给一定的延时,不然会造成翻页失败,导致下一页写操作失败。读取数据时可不用延时。最后一点,读取数据的时候如果对速度要求比较高,可以省略掉延时的部分,可能不太妥当,但是IIC的速度就是没有办法和SDHC卡比。整片的存储大小也就32K,512(page)*64(byte)。
需要说明的是在当前页内,不论是读取还是写入,操作完成后要主动接收或者发送ACK。这样做的目的是告知芯片信息已经收到,芯片会自动将当前字节地址+1,如果已是最后一字节,则地址指针会自动回滚当前页第0字节,重新写入或者读取。如果是写入页的最后一个字节,在ACK后要发送END信号。如果是接收当前页的最后一字节,接收完后不发送ACK直接发送END信号。
/****************************************************************************
函数名称:AT24C256_DataCopy
功 能:将单片机上的长数组写入AT24C256芯片中
入口参数:pbuf:指向返回数据指针
返 回 值:最大页号
备 注:只完成了基本功能,漏洞还是有的,比如存入任意大小的字符串时,
对最后一页不够64字节的数据存储还不太精确。
*****************************************************************************/
unsigned char AT24C256_DataCopy(unsigned char *pbuf, unsigned int BufLength)
{
unsigned int PageCnt = 0x0000; //页计数 2bytes
unsigned int Cnt = 0; //字节计数
unsigned int i;
unsigned char addr[2] = {0x00,0x00}; //PageCnt进行地址运算结果
while(1)
{
addr[0] = 0x7f&(PageCnt >> 2); //at24c256页地址计算 XPPP,PPPP,PPBB,BBBB X不关心,P页地址,B字节地址
addr[1] = PageCnt & 0x0003;
addr[1] = addr[1] << 6;
AT24C02_Start(); //起始信号
AT24C02_SendByte(AT24C02_ADD_WR); //发送设备地址+写信号
AT24C02_SendByte(addr[0]); //发送存储单元地址2bytes 与PageCnt
AT24C02_SendByte(addr[1]);
if((BufLength - Cnt) > 64)
{
for (i=0; i<PAGE_SIZE; i++) //写入一页的数据
{
AT24C02_SendByte(pbuf[Cnt]);
Cnt++;
}
}
else
{
for (i=0; i<(BufLength - Cnt); i++) //写入不到一页的数据
{
AT24C02_SendByte(pbuf[Cnt]);
Cnt++;
}
return PageCnt;
}
AT24C02_Stop(); //停止信号
Delay_ms(20); //非常重要的延时,不然造成下一页来不及转换,写数据失败
PageCnt++; //页地址加1
if(PageCnt >= 512)
{
PageCnt = 0;
Cnt = 0;
return 1;
}
}
}
/******************************************************************************
函数名称:AT24C256_AllDataOut
功 能:将所有的数据输出给串口
入口参数:pbuf:指向返回数据指针,数据的长度
返 回 值:无
备 注:原理大致相同
*******************************************************************************/
void AT24C256_AllDataOut(unsigned char *pbuf, unsigned int BufLength)
{
unsigned int PageCnt = 0x0000; //页计数 2bytes
unsigned int Cnt = 0; //字节计数
unsigned int i;
unsigned char addr[2] = {0x00,0x00}; //PageCnt进行地址运算结果
while(1)
{
addr[0] = PageCnt >> 2; //at24c256页地址计算 XPPP,PPPP,PPBB,BBBB X不关心,P页地址,B字节地址
addr[1] = PageCnt & 0x0003;
addr[1] = addr[1] << 6;
AT24C02_Start(); //起始信号
AT24C02_SendByte(AT24C02_ADD_WR); //发送设备地址+写信号
AT24C02_SendByte(addr[0]); //发送存储单元地址2bytes
AT24C02_SendByte(addr[1]);
AT24C02_Start(); //起始信号
AT24C02_SendByte(AT24C02_ADD_RD); //发送设备地址+读信号
if((BufLength - Cnt) > 64)
{
for (i=0; i<PAGE_SIZE; i++) //读取一页数据
{
pbuf[i] = AT24C02_RecvByte();
if (i == (PAGE_SIZE-1))
{
AT24C02_SendACK(NOACK); //最后一个数据需要NAK
}
else
{
AT24C02_SendACK(ACK); //回应ACK
}
uart_send_char(pbuf[i]); //发送到串口查看
Cnt++;
}
}
else
{
for (i=0; i<(BufLength - Cnt); i++) //读取一页数据
{
pbuf[i] = AT24C02_RecvByte();
if (i == (BufLength - Cnt-1))
{
AT24C02_SendACK(NOACK); //最后一个数据需要NAK
}
else
{
AT24C02_SendACK(ACK); //回应ACK
}
uart_send_char(pbuf[i]); //发送到串口查看
Cnt++;
}
break;
}
AT24C02_Stop(); //停止信号
PageCnt++; //页地址加1
if(PageCnt >= 512)
{
PageCnt = 0;
Cnt = 0;
break;
}
}
}