三星系列的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,即设备代码。
实践在芯片的读写操作中,还要留意对坏扇区进行检错,并将检错成果存入芯片的第一个块中,以保证数据的读写地址均为有用地址。