NAND FLASH原理与实验

  • 格式:doc
  • 大小:77.00 KB
  • 文档页数:13

NAND FLASH原理与实验 2012-10-17 12:32:02

分类: 原文地址:NAND FLASH原理与实验 作者:wangh0802 常用的FLASH主要有NOR FLASH和NAND FLASH两种:

NAND FLASH不能执行代码,主要用于存储大量数据;具有极高的单元密度,可以达到高存储密度,并且写入和檫除速度也很快;应用困难在于FLASH的管理需要特殊的系统接口。 NOR FLASH中的数据掉电不会丢失,而且可以执行程序,常用于存储系统的启动代码;特点是芯片内执行(XIP),应用程序可以直接在NOR FLASH内运行,不需要再把代码读到系统RAM中。很低的写入和檫除速度大大影响了它的性能。 为什么NAND FLASH无法执行程序呢?这主要是由于NAND FLASH的接口主要包括几个I/O口,对其中数据的访问是穿行的访问,无法实现随机访问,因此NAND FLASH无法执行程序。 因为NAND FLASH接口电路是通过NAND FLASH控制器与S3C2440处理器相接的,因为读者不需要关心具体的访问时序,之所以提供NAND FLASH控制器就是为了便于使用NAND FLASH。如果没有NAND FLASH控制器,则需要产生相应的访问时序。 NAND FLASH的存储器组成主要有两部分:页(Page)、块(BIock)。以K9F2G08U0B为例: 每页大小为:2K 64字节,2K字节用来存储数据,64字节主要用来存储控制信息,主要是为了便于管理每一页。 每块大小为:64个页;整个NAND FLASH由2K(2048)个块组成(128KPages)。 从数据输出可以看到K9F2G08U0B的容量是256MBytes*8Bit,怎么算出来的呢? NAND FLASH容量=块的数目*每块的容量 =块的数目*(每块包含页的数目*每页的容量) =2K块*(64页*(2KBytes 64Bytes)) =2K块*64页*2KBytes 2K块*64页*64Bytes =256MBytes 8MBytes(256MBytes表示该NAND FLASH可以存储256M个字节数据,后面的8M字节的数据主要用于保存每一页的控制信息) 1K(Bytes)=1024字节,1M(Bytes)=1K(Bytes)*1K(Bytes); NAND FLASH接口电路: S3C2440处理器内部已经集成了NAND FLASH控制器,因此,接口电路将变得很简单,只需要将S3C2440处理器对应引脚和NAND FLASH的对应引脚接上即可。 但是不同的NAND FLASH的容量不一样,接口线宽不一样,S3C2440处理器如何获得这些信息呢?先对NAND FLASH控制器的作用进行简单的总结: 1.提供外接NAND FLASH的接口信息,包括接口线宽、容量等信息。 2.提供访问NAND FLASH所需要的时序信息。 S3C2440处理器提供了如下方法来识别NAND FLASH接口线宽和容量,OM[1:0]、NCON、GPG13、GPG14和GPG15共5个信号来选择NAND FLASH启动。 OM[1:0]:当两个引脚均为低电平是,从NAND FLASH启动。 NCON:NAND FLASH的类型选择信号。0、正常型NAND FLASH;1、高级型NAND FLASH; GPG13:NAND FLASH页容量选择信号。0、256Word(NCON=0)或1KWords(NCON=1); 1、512Bytes(NCON=0)或2KBytes(NCON=1); GPG14:NAND FLASH地址周期选择。0、3地址周期(NCON=0)或4地址周期(NCON=1)。 1、4地址周期(NCON=0)或5地址周期(NCON=1)。 GPG15:NAND FLASH接口线宽选择。0、8位总线宽度。1、16位总线宽度。 如何访问NAND FLASH? 发送命令,即对NAND FLASH采取哪种操作,读,写还是擦除; 发送地址,即对NAND FLASH的哪一页进行上述操作; 发送数据,在此期间要检测NAND FLASH的内部状态。 NAND FLASH内部的地址如何确定呢?从对应数据手册上可以找到有关地址序列的信息: 所谓的列地址即在一页中的地址,因为每页大小是2K 64Bytes,所以需要12根地址线来寻址,也即A0~A11,整个NAND FLASH包含128K个页面,则需要17跟地址线来寻址一个页面,即A12~A28,这也就是所谓的行地址。 S3C2440 NAND FLASH控制器,初始化只需要根据K9F2G08U0B数据手册给出的时序参数,正确初始化S3C2440处理器相关的寄存器即可。1.配置GPACON寄存器,将GPA17~GPA22设置为NAND FLASH控制器信号模式。2.配置NAND FLASH,主要是初始化寄存器NFCONF. A.寄存器NFCONT,用于开启NAND FLASH控制器。 B.向寄存器NFCMD写入命令。向NAND FLASH发送命令,只需要将命令写入该寄存器即可,NAND FLASH控制器会根据上述参数自动产生出访问NAND FLASH所需要的命令信号。 C.向NAND FLASH发送命令:#define NF_CMD(cmd) {rNFCMD=(cmd);} D.向寄存器NFADDR写入地址:#define NF_ADDR(addr) {rNFADDR=(addr);} E.使用寄存器NFDATA进行数据读写,在此期间需要检查NFSTAT来检测NAND FLASH的状态。 F.寄存器NFSTAT,用于指示NAND FLASH是否处于忙状态。 #define NF_DETECT_RB() {while(!(rNFSTAT&(1<<2)));} 使用宏代替简单的函数: 在程序开发过程中,经常将一个很大的工程分解为几个小的模块,每个模块使用单独的函数来实现,最后在工程中通过对各个模块函数的调用来实现整个工程所完成的功能,这也是典型的模块化开发技巧。但是,项目中调用关系复杂,尤其是存在多级函数调用时,需要将每一级的返回地址保存在栈中,容易导致溢出,此外函数调用开销也会增大。 为了更好地解决上述问题,一般使用宏的形式来实现规模较小的函数。因为宏调用是预处理阶段,由预处理器对源程序中的宏进行展开,所以宏展开不占用运行时间。因为每一次宏调用都需要进行宏展开,所以会加大程序的代码量,因此规模较大的函数不宜使用宏的形式来实现。 #define rNFCONT (*(volatile unsigned *)0x4E000004) 等等 具体操作函数: #define NF_Enable() {rNFCONT &=~(1<<1);} #define NF_Disable() {rNFCONT |=~(1<<1);} #define NF_Send_Cmd(cmd) {rNFCONT =(cmd);} #define NF_Send_Addr(addr) {rNFADDR =(addr);} #define NF_Send_Data(data) {rNFDATA8 =(data);} #define NF_Enable_RB() {rNFSTAT|=(1<<2);}开启忙检测功能 #define NF_Check_Busy() {while(!(rNFSTAT&(1<<2)));}检测NAND FLASH是否处于忙状态。 #define NF_Read_Byte() {rNFDATA8} NAND FLASH基本操作函数分析:其中包括复位,初始化,页写入,页读入,快擦除等操作函数。(一般使用命令,是将所有的命令以宏的形式定义好,以后使用的时候直接使用相应的宏即可) NAND FLASH复位函数: 1. static void NF_Reset()

2. { 3. NF_Enable();//打开片选信号

4. NF_Enable_RB();//开启忙信号检测 5. NF_Send_Cmd(CMD_RESET);//发送复位命令 6. NF_Check_Busy();//检测忙信号 7. NF_Disable();//关闭片选信号 8. } NAND FLASH初始化函数:将相应的时序参数写入NAND FLASH控制

器即可。分析TACLS、TWRPH0、TWRPH1的值。需要分别与芯片时间对应关系。tCLS-tWP、tWP、tCLH对应。 查对应芯片手册:tCLS=12ns、tWP=12ns、tCLH=5ns(参考值,实际可长),则TACLS=1、TWRPH1=4、TWRPH1=0. 1. #define TACLS 1

2. #define TWRPH0 4 3. #define TWRPH1 0 4. void NF_Init(void) 5. { 6. rGPACON &=~(0X3f<<17);

7. rGPACON |=(0X3F<<17); //GPA17~GPA22设置为NAN

D FLASH控制器信号输出模式;