你是否还记得我上文提到过的Data Field被分为1st half 和2end half两个部分?而从上面的命令集我们看到Read1的命令里面出现了两个命令选项,分别是00h和01h。这里出现了两个读命是否令你意识到什么呢?是的,00h是用于读写1st half的命令,而01h是用于读取2nd half的命令。现在我可以结合上给你说明为什么K
如上文我所提及的,Read1的1st.Cycle是发送Column Address,假设我现在指定的Column Address是0,那么读操作将从此页的第0号Byte开始一直读取到此页的最后一个Byte(包括Spare Field),如果我指定的Column Address是127,情况也与前面一样,但不知道你发现没有,用于传递Column Address的数据线有8条(I/O0~I/O7,对应A0~A7,这也是A8为什么不出现在我们传递的地址位中),也就是说我们能够指定的Column Address范围为0~255,但不要忘了,1个Page的DataField是由512个Byte组成的,假设现在我要指定读命令从第256个字节处开始读取此页,那将会发生什么情景?我必须把Column Address设置为256,但Column Address最大只能是255,这就造成数据溢出。。。正是因为这个原因我们才把Data Field分为两个半区,当要读取的起始地址(Column Address)在0~255内时我们用00h命令,当读取的起始地址是在256~511时,则使用01h命令.假设现在我要指定从第256个byte开始读取此页,那么我将这样发送命令串
column_addr=256;
NF_CMD=0x01; // 从2nd half开始读取
NF_ADDR=column_addr&0xff; // 1st Cycle
NF_ADDR=page_address&0xff; // 2nd.Cycle
NF_ADDR=(page_address>>8)&0xff; // 3rd.Cycle
NF_ADDR=(page_address>>16)&0xff; // 4th.Cycle
其中NF_CMD和NF_ADDR分别是NandFlash的命令寄存器和地址寄存器的地址解引用,我一般这样定义它们
#define rNFCMD (*(volatile unsigned char *)0x4e000004) //NAND Flash command
#define rNFADDR (*(volatile unsigned char *)0x4e000008) //NAND Flash address
事实上,当NF_CMD=0x01时,地址寄存器中的第8位(A8)将被设置1(如上文分析,A8位不在我们传递的地址中,这个位其实就是硬件电路根据01h或是00h这两个命令来置高位或是置低位),这样我们传递column_addr的值256随然由于数据溢出变为1,但A8位已经由于NF_CMD=0x01的关系被置为1了,所以我们传到地址寄存器里的值变成了
A0 A1 A2 A3 A4 A5 A6 A7 A8
1 0 0 0 0 0 0 0 1
这8个位所表示的正好是256,这样读操作将从此页的第256号byte(2nd half的第0号byte)开始读取数据。
Read2: Read2则是指定读取Spare Field的内容。其实Read1和Read2都是读命令,他们的区别相当于对一个读指针进行不同区域的定位。如图所示: