NOR FLASH 和NAND FLASH主要区别
NOR地址线和数据线分开,NAND闪存芯片因为共用地址和数据总线
NOR容量较小,NAND容量较大
在擦除速度上,NAND比NOR快
在NOR型Flash上运行代码不需要任何的软件支持,而在NAND型Flash上进行同样操作时,通常需要驱动程序,即内存技术驱动程序MTD
NAND FLASH
NandFlash的数据是以bit 的方式保存在memory cell里的,一般来说,一个cell 中只能存储一个bit,这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 组成Page, page 再组织形成一个Block。k9f1208的相关数据如下:
1block=32page;1page=528byte=512byte(Main Area)+16byte(Spare Area)。
总容量为=4096(block数量)*32(page/block)*512(byte/page)=64Mbyte
NandFlash以页为单位读写数据,而以块为单位擦除数据。按照k9f1208的组织方式可以分四类地址: Column Address、halfpage pointer、Page Address 、Block Address。A[0:25]表示数据在64M空间中的地址。
Column Address表示数据在半页中的地址,大小范围0~255,用A[0:7]表示;
halfpage pointer表示半页在整页中的位置,即在0~255空间还是在256~511空间,用A[8]表示;
Page Address表示页在块中的地址,大小范围0~31,用A[13:9]表示;
Block Address表示块在flash中的位置,大小范围0~4095,A[25:14] 表示;
命令集
⑴ Read 1
命令是00h/01h,这两个命令用于读取datafield的数据,其中00h表示将要读取K9F1208U0B存储空间中一个页的前半部分,并且将内置指针定位到前半部分的第一个字节;01h表示将要读取K9F1208U0B存储空间中一个页的后半部分,并且将内置指针定位到后半部分的第一个字节。
⑵ Read 2
命令是50h,用于读取sparefield的数据。
⑶ Read ID
命令是90h,读取nandflash芯片的ID号
⑷ Reset
命令是FFh,重启nandflash芯片。
⑸ Page Program
对页进行编程命令,由于写操作,首先写入00h(A区)/01h(B区)/50h,表示写入那个区;再写入80h开始编程模式(写入模式),接下来写入地址和数据,最后写入10h表示编程结束。
⑹ Block Erase
块擦除命令,首先写入60h进入擦写模式,然后输入块地址;接下来写入D0h,表示擦写结束。
例如
static void ReadPage(U32 addr, U8 *buf) //addr表示flash中的第几页,即‘flash地址>>9’
{ U16 i;
NFChipEn(); //使能NandFlash
WrNFCmd(READCMD0); //发送读指令‘0x00’,由于是整页读取,所以选用指令‘0x00’
WrNFAddr(0); //写地址的第1个cycle,即Column Address,由于是整页读取所以取0
WrNFAddr(addr); //写地址的第2个cycle,即A[9:16]
WrNFAddr(addr>>8); //写地址的第3个cycle,即A[17:24]
WrNFAddr(addr>>16); //写地址的第4个cycle,即A[25]。
WaitNFBusy(); //等待系统不忙
for(i=0; i<512; i++)
buf = RdNFDat(); //循环读出1页数据 NFChipDs(); //释放NandFlash
}
static void WritePage(U32 addr, U8 *buf) //addr表示flash中的第几页,即‘flash地址>>9’
{ U32 i;
NFChipEn(); //使能NandFlash
WrNFCmd(PROGCMD0); //发送写开始指令’0x80’
WrNFAddr(0); //写地址的第1个cycle
WrNFAddr(addr); //写地址的第2个cycle
WrNFAddr(addr>>8); //写地址的第3个cycle
WrNFAddr(addr>>16); 写地址的第4个cycle
WaitNFBusy(); //等待系统不忙
for(i=0; i<512; i++)
WrNFDat(buf); //循环写入1页数据
WrNFCmd(PROGCMD1); //发送写结束指令’0x10’
NFChipDs(); //释放NandFlash
}
NOR FLASH
SST39VF1601NorFlash
** 器件特性:随机读写,按扇区、块、整片擦除,写数据前必须擦除数据地址所在的扇区。
** 器件容量:1Mb * 16
** = 2MB
** = 512个扇区 * 2048字/扇区(1字=2字节)
** = 32个块 * 16个扇区/块 * 2048字/扇区(1字=2字节)
#define GetAddr(addr) (volatile uint16 *)(FLASH_ADDR|(addr<<1)) //CPU A1 接 FLASH的 A0(为何如此,CPU地址是按字节递增),因此要右移1位
/**********************************************************************Function name: WordProgram
**Descriptions: 半字(16位)数据编程。
**Input: Addr 编程地址(SST39VF1601内部地址)
** Data 编程数据
**Output: 返回TRUE表示操作成功,返回FALSE表示操作失败
**Last modified Date: 2011-12-13
**-------------------------------------------------------------------
**Modified by:
**Modified Date:
**-------------------------------------------------------------------
********************************************************************/
int WordProgram(uint32 Addr, uint16 Data)
{
volatile uint16 *ip;
uint16 temp1,temp2;
ip = GetAddr(0x5555); // 转换地址0x5555
ip[0] = 0xaaaa; // 第一个写周期,地址0x5555,数据0xAA
ip = GetAddr(0x2aaa);
ip[0] = 0x5555; // 第二个写周期,地址0x2aaa,数据0x55
ip = GetAddr(0x5555);
ip[0] = 0xa0a0; // 第三个写周期,地址0x5555,数据0xA0
ip = GetAddr(Addr);
*ip = Data; // 第四个写周期,地址Addr,数据Data
temp1 = *ip; // 预读处理
while(1) // 等待操作完成 (若编程操作没有完成,每次读操作DQ6会跳变)
{
temp1 = *ip;
temp2 = *ip;
if(temp1 == temp2)
{
if(temp1 != Data)
{
return(FALSE);
}
else
{
return(TRUE);
}
} // end of if(temp1 == temp2)...
} // end of while(1)...
return(TRUE);
}