在NAND Flash中有8个I/O引脚(IO0—IO7)、5个全能信号(nWE ALE CLE nCE nRE)、一个引脚,1个写保护引脚。操作NAND Flash时,先传输命令,然后传输地址,最后读写数据。对于64MB的NAND Flash,需要一个26位的地址。只能8个I/O引脚充当地址、数据、命令的复用端口,所以每次传地址只能传8位。这样就需要4个地址序列。因此读写一次nand flash需要传送4次(A[7:0] A[16:9] A[24:17] A[25])。64M的NAND Flash的地址范围为0x00000000—0x03FFFFFF。128M的NAND Flash的地址范围为0x00000000---0x07FFFFFF。1KB = 0x000-0x3FF.128字节=0x00H--7FH。 一页有528个字节,而在前512B中存放着用户的数据。在后面的16字节中(OOB)中存放着执行命令后的状态信息。主要是ECC校验的标识。列地址A0-A7可以寻址的范围是256个字节,要寻址528字节的话,将一页分为了A.(1half array)B(2 half array) C(spare array)。A区0—255字节,B区 256-511 字节C区512—527字节。访问某页时必须选定特定的区。这可以使地址指针指向特定的区实现。 在NAND Flash 中存在三类地址,分别为Block Address 、Column Address Page Address.。(实际就是块地址和页地址) Column Address 用来选择是在上半页寻址还是在下半页寻址A[0]—A[7].也就相当于页内的偏移地址。在进行擦除时不需要列地址,因为擦除是以块为单位擦除。32个Page需要5bit来表示。也就是A[13:9];也就是页在块内的相对地址。A8这一位用来设置512字节的上半页,还是下半页,1表示是在上半页,而2表示是在下半页。Block的地址有A[25:14]组成. 一个容量为64M(512Mbit)的NAND Flash,分为131072页,528列。(实际中由于存在spare area,故都大于这个值),有4096块,需要12bit来表示即A[25:14].如果是128M(1Gbit)的话,blodk Address为A[26:14].由于地址只能在IO0—IO7上传送。编程时通常通过移位来实现地址的传送。传送过程如下: 第1个地址序列:传递column address,也就是NAND Flash[7:0],这一周期不需要移位即可传递到I/O[7:0]上,而half page pointer 即A8是由操作指令决定,00h,在A区,01h在B区,指令决定在哪个half page上进行读写,而真正A8的值是不需要程序员关心的; 第2个地址序列:就是将NAND_ADDR 右移9位,而不是8位,将NAND_ADDR[16:9]传递到I/O[7:0]上; 第3个地址序列:将NAND_ADDR[24:17] 传递到I/O[7:0]上; 第4个地址序列:将NAND_ADDR[25]传送到I/O上。 整个地址的传送过程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的话,那么block address 最高位只到bit24,因此寻址只需要3步,就可以完成。 在进行擦除操作时由于是以块进行擦除,所以只需要3个地址序列,也就是只传递块的地址,即A[14:25]。 NAND Flash地址的计算: Column Address 翻译过来是列地址,也就是在一页里的偏移地址。其实是指定Page上的某个Byte,指定这个Byte,其实也就是指定此页的读写起始地址。 Page Address:页地址。页的地址总是以512Bytes对齐的,所以它的低9位问题0,确定读写操作在NAND Flash中的哪个页进行。 当我们得到一个Nand Flash地址addr时,我们可以这样分解出Column Address和Page Address。 Columnaddr = addr % 512 // column address Pageaddr = addr>>9 // page address 实际上A0~A7是页内陆址,比如从第2个开始读起。不过一般都从0开始读起,呵呵。 也就是一个Nand Flash地址的A0-A7是它的column address ,A9—A25是它的Page Address,地址A8被忽略。 现在假设我要从Nand Flash中的第5000字节处开始读取1024个字节到内存的0x30000000处,我们这样调用read函数 NF_Read(5000, 0x30000000,1024); 我们来分析5000这个src_addr. 根据: column_addr=src_addr%512; page_address=(src_addr>>9); 我们可得出column_addr=5000%512=392 page_address=(5000>>9)=9 于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的NF_read函数将这样发送命令和参数 column_addr=5000%512; page_address=(5000>>9); NF_CMD=0x01; //要从2nd half开始读取 所以要发送命令0x01 NF_ADDR= column_addr &0xff; //1st Cycle A[7:0] NF_ADDR=page_address& 0xff NF_ADDR=(page_address>>8)&0xff; //3rd.Cycle A[24:17] NF_ADDR=(page_address>>16)&0xff; //4th.Cycle A[25] 向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了. 我用下面的代码进行数据的读取. for(i=column_addr;i<512;i++) *buf++=NF_RDDATA(); 每当读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte). //========================下面是另外一篇,差不多===================== 一、NAND flash的物理组成 二、NAND Flash地址的表示 |
联系客服