三星系列的NANDFLASH芯片容量从8MB到256MB(最近听说有1G容量的了),对于需要大容量数据存储的嵌入式系统是一个很好的选择,尤其是其接近1MB/元的高性价比,更是普通norflash无法比拟的。本文以K9F2808U0C为例,采用AVR芯片连接,进行了初步的读写试验,完成了芯片的ID读出功能。电路连接如下图:左边是所使用的AVR芯片ATmega16L的局部电路,右边是K9F2808芯片的连接图,数据/地址总线使用ATmega16的PORTB端口连接,其它全部所需信号线使用IO连接,组成了IO模拟方式。K9F2808芯片的全部命令字如下:其中,Read1读取的是普通数据存储区域的数据,Read2读取的是每页存储器附加的16Bytes区域的数据;PageProgram可以编程一页最大528Bytes的数据,BlockErase擦除指定页面数据,ReadStatus可以读取芯片状态。芯片的整个读写时序可以分解为4个基本步骤,即1、命令写入,2、数据写入,3、数据读出,4、地址写入。1、命令写入时序如下:对应函数为:voidWriteCmd(unsignedcharcmd){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、数据写入时序如下:对应函数为:voidWriteByte(unsignedcharWdata){nandPortD=0xFF;SetLine(nandSPortO,nandnWE);ClsLine(nandSPortO,nandCLE);ClsLine(nandSPortO,nandnCE);ClsLine(nandSPortO,nandALE);ClsLine(nandSPortO,nandnWE);while((nandSPortI&nandRnB)!=nandRnB);//waitbusyendnandPortO=Wdata;while((nandSPortI&nandRnB)!=nandRnB);//waitbusyendSetLine(nandSPortO,nandnWE);}3、数据读出时序如下:对应函数为:unsignedcharReadByte(void){unsignedcharRdata;nandPortD=0x00;SetLine(nandSPortO,nandnWE);ClsLine(nandSPortO,nandCLE);ClsLine(nandSPortO,nandALE);ClsLine(nandSPortO,nandnCE);ClsLine(nandSPortO,nandnRE);while((nandSPortI&nandRnB)!=nandRnB);//waitbusyendRdata=nandPortI;while((nandSPortI&nandRnB)!=nandRnB);//waitbusyendSetLine(nandSPortO,nandnRE);returnRdata;}4、地址写入时序如下:对应函数为:voidWriteByteAdd(unsignedcharAdd){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);//waitbusyendClsLine(nandSPortO,nandALE);}其余操作方式均从这四种基本操作组合变化而来,适当调用或者重新编写其中的某些语句就能完成全部的K9F2808芯片读写操作。下面以读K9F2808芯片ID为例调用以上函数完成。读芯片ID的时序如下图:实现函数编写为:voidReadId(unsignedchar*ptr){WriteCmd(0x90);WriteByteAdd(0x00);*ptr++=ReadByte();*ptr=ReadByte();SetLine(nandSPortO,nandnCE);}函数调用后,*ptr的值为0xEC,即厂家代码;*(ptr+1)的值为0x73,即设备代码。实际在芯片的读写操作中,还要注意对坏扇区进行检错,并将检错结果存入芯片的第一个块中,以确保数据的读写地址均为有效地址。