Nand Flash介绍和Nand Flash控制器使用
一、Flash介绍 ??? 常用的flash类型有NOR Flash 和Nand Flash 两种; ??? (1)Nor Flash ????1、Nor Flash的接口和RAM完全相同,可以随机访问任意地址的数据,在其上进行读操作的效率非常高,但是擦除和写操作的效率很低,另外,Nor Flash的容量一般比较小,通常,Nor Flash用于存储程序; ??? (2)Nand Flash 通常Nand Flash用于存储数据; ? 二、Nand? Flash的物理结构 ??? 以三星公司生产的 K9F1208U0M? 为例: ????1、容量:64MB, ????????????????????? 一共4个层; ??????????????????????每层1024个块(block); ??????????????????????1块包含32页 ??????????????????????1页包含 512 + 16? = 528个字节 ? ? ????2、外部接口:8个I/O口,5个使能信号(ALE、CLE、nWE、nRE、nCE),1个状态引脚(RDY/B),1个写保护引脚(nWE);???????????? ????3、命令、地址、数据都通过8个I/O口输入输出; ??? 4、写入命令、地址、数据时,都需要将nWE、nCE信号同时拉低;数据在WE上升沿被锁存; ??? 5、CLE、ALE用来区分I/O引脚上传输的是数据还是地址; ????6、64MB的空间需要26位地址,因此以字节为单位访问Flash时需要4个地址序列; ??? 7、读/写页在发出命令后,需要4个地址序列,而擦除块在发出擦除命令后仅需要3个地址序列; ? 三、Nand Flash访问方法
?1 特殊功能寄存器定义?
#define rNFCONF ?(*(volatile unsigned int *)0x4e000000)?
#define rNFCMD ? (*(volatile unsigned char *)0x4e000004)?
#define rNFADDR ?(*(volatile unsigned char *)0x4e000008)?
#define rNFDATA ?(*(volatile unsigned char *)0x4e00000c)?
#define rNFSTAT ?(*(volatile unsigned int *)0x4e000010)?
#define rNFECC ? (*(volatile unsigned int *)0x4e000014)?
#define rNFECC0 (*(volatile unsigned char ?*)0x4e000014)?
#define rNFECC 1 (*(volatile unsigned char *)0x4e000015)?
#define rNFECC2 (*(volatile unsigned char *)0x4e000016)?
2 操作的函数实现?
1. 发送命令?
#define NF_CMD(cmd) ? ?{rNFCMD=cmd; }?
2. 写入地址?
#define NF_ADDR(addr) ?{rNFADDR=addr;}?
3. Nand Flash 芯片选中?
#define NF_nFCE_L() ? ?{rNFCONF&=~(1<<11);}?
4. Nand Flash 芯片不选中?
#define NF_nFCE_H() ? ?{rNFCONF|=(1<<11);}?
5. 初始化 ECC?
#define NF_RSTECC() ? ?{rNFCONF|=(1<<12);}
?
6. 读数据?
#define NF_RDDATA() ? ? ? ? (rNFDATA)?
7. 写数据?
#define NF_WRDATA(data) {rNFDATA=data;}?
8. 获取Nand Flash 芯片状态?
#define NF_WAITRB() ? ? ? ? {while(!(rNFSTAT&(1<<0)));}?
0/假: 表示Nand Flash 芯片忙状态?
1/真:表示Nand Flash 已经准备好?
3.NandFlash读写擦具体实现。
????? 操作Nand? Flash时,先传输命令,然后传输地址,最后读、写数据,期间要检查flash的状态; ????? K9F1208U0M? 一页大小为528字节,而列地址A0——A7可以寻址的范围是256字节,所以将一页分为A、B、C三个区: ?????????????????A区:0—255字节 ???????????????? B区:256—511字节 ???????????????? C区:512—527字节 ?(0)Nand Flash 初始化? (1)复位 ????????? 命令:FFh ??????????步骤:发出命令即可复位Nand Flash芯片; ?static void NF_Reset(void)? (2)读操作 ????????? 命令: ???????????????? 00h——读A区 ???????????????? 01h——读B区 ???????????????? 50h——读C区 ???????????操作步骤: ????????????? 1、发出命令 00h、01h 或50h,? 00h将地址位A8设为0,? 01h将A8设为1?; ??????????????2、依次发出4个地址序列; ????????????? 3、检测R/nB,待其为高电平时,就可以读取数据了; 参数说明:block :块号? /* 读取该页的OOB 块 */? (3)flash编程 ????????? ? 命令: ?????????????????? 80h——10h?:写单页; ???????????????????80h——11h?:对多个层进行些页操作;???? ?????????????操作步骤: ?????????????????1、写单页步骤: ??????????????????????????? 【1】发出80h命令后; ????????????????????????????【2】发送4个地址序列; ????????????????????????????【3】向flash发送数据; ????????????????????????????【4】发出命令10h启动写操作,flash内部自动完成写、校验操作; ????????????????????????????【5】通过命令70h读取状态位,查询写操作是否完成; ??????????????????2、多页写 ????????????????????????????【1】发出80h、4个地址序列、最多528字节的数据; ????????????????????????????【2】发出11h命令; ????????????????????????????【3】接着在相邻层执行【1】、【2】两步操作; ????????????????????????????【4】第四页的最后使用10h代替11h,启动flash内部的写操作; ????????????????????????????【5】可以通过71h查询写操作是否完成; 以页为单位写入.? ? if (NF_RDDATA()&0x1)? (4)复制 ???????????????命令: ???????????????????? 00h——8Ah——10h? :单层页内复制 ???????????????????? 03h——8Ah——11h? :多层页内复制 ???????????????操作步骤: ?????????????????? 1、单层页内复制步骤: ????????????????????????????【1】发出命令00h; ??????????????????????????? 【2】4个源地址序列; ????????????????????????????【2】接着发出8Ah; ????????????????????????????【4】发出4个目的地址序列; ??????????????????????????? 【5】发出10h命令,启动写操作; ????????????????????????????【6】通过70h命令读取状态查询操作是否完成; ???????????????????2、多层页内复制步骤: ?????????????????????????????【1】发出命令00h(第一层)、4个源页地址序列; ???????????????????????????? 【2】以后各层依次发出命令03h、4个源页地址序列; ???????????????????????????? 【3】发出命令8Ah、目的地址、命令11h; ?????????????????????????????【4】各层依次执行【3】,在最后一页的地址后,用10h代替11h,启动写操作; ???????????????????????????? 【5】通过71h命令读取状态查询操作是否完成; (5)擦除 ?????????????? 命令: ???????????????????? 60h——D0h? :单层内块擦除 ?????????????????????60h-60h ——D0h? :多层内块擦除 ?????????????? 操作步骤: ??????????????????1、单层内块擦除: ??????????????????????????????【1】发出命令字60h; ??????????????????????????????【2】发出块(block)地址,仅需3个地址序列; ??????????????????????????????【3】发出D0h,启动擦除操作; ????????????????????????????? 【4】发出70h命令查询状态,是否完成擦除; ???????????????????2、多层内块擦除: ??????????????????????????????【1】发出命令字60h,3个块地址序列; ??????????????????????????????【2】对每个层执行【1】; ????????????????????????????? 【3】发出命令D0h,启动擦除操作; ??????????????????????????????【4】发出71h命令查询状态,检查是否完成擦除; (6)读取芯片ID ???????????????? 命令:90h ???????????????? 操作步骤: ???????????????????? 1、发出命令90h; ?????????????????????2、发出4个地址序列(均设为0); ?????????????????????3、连续读入5个数据,分别表示:厂商代码、设备代码、保留字节、多层操作代码; 返回值为Nand flash 芯片的 ID 号? (7)读状态 ?????????????????命令: ???????????????????????70h——单层状态 ?????????????????????? 71h——多层状态 ???????????????? 操作步骤:写入命令字之后,然后启动读操作即可读入此寄存器。 (8)Nand flash 标记坏块? /*读NandFlash 的写状态 */? (9)Nand Flash 检查坏块? (10)擦除指定块中数据? 1 :成功擦除。? ?static int NF_EraseBlock(unsigned int block)? ?{? ? ? ?unsigned int blockPage=(block<<5);? ? ? ?int i;? ? ? ?/* 如果该块是坏块,则返回 */? ? ? ?if(NF_IsBadBlock(block))? ? ? ? ? ?return 0;? ? ? ?NF_nFCE_L(); ? ? ?/* 片选 Nand Flash 芯片*/? ? ? ?NF_CMD(0x60); ? ? /* 设置擦写模式 ? ? ?*/? ? ? ?NF_ADDR(blockPage&0xff); ? ? ? /* A9-A 16,(Page Address),是基于块擦*/? ? ? ?NF_ADDR((blockPage>>8)&0xff); ? ? ? ?/* A17-A24,(Page Address) */? ? ? ?NF_ADDR((blockPage>> 16)&0xff); ?/* A25,(Page Address) */? ? ? ?NF_CMD(0xd0); ? ? /* 发送擦写命令,开始擦写 */? ? ? ?/* 等待NandFlash 准备好 */? ? ? ?for(i=0;i< 10;i++); /* tWB(100ns) */? ? ? ?NF_WAITRB();? ? ? ?/* 读取操作状态 ? ? ? ? */? ? ? ?NF_CMD(0x70);? ? ? ?if (NF_RDDATA()&0x1)? ? ? ?{? ? ? ? ? ? ? ? ? ?NF_nFCE_H(); /* 取消Nand Flash 选中*/? ? ? ? ? ? ? ? ? ?NF_MarkBadBlock(block); /* 标记为坏块 */? ? ? ? ? ? ? ? ? ?return 0;? ? ? ?} ?else ?{? ? ? ? ? ? ? ? ? ?NF_nFCE_H(); /* 取消Nand Flash 选中*/? ? ? ? ? ? ? ? ? ?return 1;? ? ? ?}? ?}? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |