微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > MCU和DSP > 用IO模拟方式读写三星系列的NAND FLASH

用IO模拟方式读写三星系列的NAND FLASH

时间:03-04 来源:超前科技开发网 点击:
三星系列的NAND FLASH芯片容量从8MB到256MB(最近听说有1G容量的了),对于需要大容量数据存储的嵌入式系统是一个很好的选择,尤其是其接近1MB/元的高性价比,更是普通nor flash无法比拟的。本文以K9F2808U0C为例,采用AVR芯片连接,进行了初步的读写试验,完成了芯片的ID读出功能。

电路连接如下图:


左边是所使用的AVR芯片ATmega16L的局部电路,右边是K9F2808芯片的连接图,数据/地址总线使用ATmega16的PORTB端口连接,其它全部所需信号线使用IO连接,组成了IO模拟方式。

K9F2808芯片的全部命令字如下:

其中,Read1读取的是普通数据存储区域的数据,Read2读取的是每页存储器附加的16Bytes区域的数据;Page Program可以编程一页最大528Bytes的数据,Block Erase擦除指定页面数据,Read Status可以读取芯片状态。

芯片的整个读写时序可以分解为4个基本步骤,即1、命令写入,2、数据写入,3、数据读出,4、地址写入。

1、命令写入时序如下:

对应函数为:
void WriteCmd(unsigned char cmd)
{
nandPortD = 0xFF;
ClsLine(nandSPortO,nandALE);
ClsLine(nandSPortO,nandnCE);
SetLine(nandSPortO,nandCLE);
ClsLine(nandSPortO,nandnWE);
nandPortO = cmd;
SetLine(nandSPortO,nandnWE);
ClsLine(nandSPortO,nandCLE);
SetLine(nandSPortO,nandALE);
}

2、数据写入时序如下:

对应函数为:
void WriteByte(unsigned char Wdata)
{
nandPortD = 0xFF;
SetLine(nandSPortO,nandnWE);
ClsLine(nandSPortO,nandCLE);
ClsLine(nandSPortO,nandnCE);
ClsLine(nandSPortO,nandALE);
ClsLine(nandSPortO,nandnWE);
while((nandSPortI & nandRnB) != nandRnB); // wait busy end
nandPortO = Wdata;
while((nandSPortI & nandRnB) != nandRnB); // wait busy end
SetLine(nandSPortO,nandnWE);
}

3、数据读出时序如下:

对应函数为:
unsigned char ReadByte(void)
{
unsigned char Rdata;
nandPortD = 0x00;
SetLine(nandSPortO,nandnWE);
ClsLine(nandSPortO,nandCLE);
ClsLine(nandSPortO,nandALE);
ClsLine(nandSPortO,nandnCE);
ClsLine(nandSPortO,nandnRE);
while((nandSPortI & nandRnB) != nandRnB); // wait busy end
Rdata = nandPortI;
while((nandSPortI & nandRnB) != nandRnB); // wait busy end
SetLine(nandSPortO,nandnRE);
return Rdata;
}

4、地址写入时序如下:

对应函数为:
void WriteByteAdd(unsigned char Add)
{
nandPortD = 0xFF;
SetLine(nandSPortO,nandnWE);
ClsLine(nandSPortO,nandnCE);
ClsLine(nandSPortO,nandCLE);
SetLine(nandSPortO,nandALE);
ClsLine(nandSPortO,nandnWE);
nandPortO = Add;
SetLine(nandSPortO,nandnWE);
while((nandSPortI & nandRnB) != nandRnB); // wait busy end
ClsLine(nandSPortO,nandALE);
}

其余操作方式均从这四种基本操作组合变化而来,适当调用或者重新编写其中的某些语句就能完成全部的K9F2808芯片读写操作。

下面以读K9F2808芯片ID为例调用以上函数完成。
读芯片ID的时序如下图:

实现函数编写为:
void ReadId(unsigned char *ptr)
{
WriteCmd(0x90);
WriteByteAdd(0x00);
*ptr++ = ReadByte();
*ptr = ReadByte();
SetLine(nandSPortO,nandnCE);
}
函数调用后,*ptr的值为0xEC,即厂家代码;*(ptr+1)的值为0x73,即设备代码。

实际在芯片的读写操作中,还要注意对坏扇区进行检错,并将检错结果存入芯片的第一个块中,以确保数据的读写地址均为有效地址。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top