S3C2440对Nand Flash操作和电路原理(基于K9F2G08U0A)
(3)使用CVAVR中的编程下载程序时应特别注意,由于CVAVR编程下载界面初始打开时,大部分熔丝位的初始状态定义为“1”,因此不要使用其编程菜单选项中的“all”选项。此时的“all”选项会以熔丝位的初始状态定义来配置芯片的熔丝位,而实际上其往往并不是用户所需要的配置结果。如果要使用“all”选项,应先使用“read-> for(i=5;i> NF_ADDR((addr >> NF_ADDR((addr >> rNFMECCD1=((mecc0&0xff000000)>>8)|((mecc0&0xff0000)>> temp = rNF_IsBadBlock(page_number>> ) & 0xff);//行地址A12~A19 NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27 NF_ADDR((page_number >> 16) & 0xff); //行地址A28 for (i = 0; i < 2048; i++)//写入一页数据 { NF_WRDATA8((char)(i+6)); } NF_MECC_Lock();//锁定main区的ECC值 mecc0=rNFMECC0; //读取main区的ECC校验码 //把ECC校验码由字型转换为字节型,并保存到全局变量数组ECCBuf中 ECCBuf[0]=(U8)(mecc0&0xff); ECCBuf[1]=(U8)((mecc0>>8) & 0xff); ECCBuf[2]=(U8)((mecc0>>16) & 0xff); ECCBuf[3]=(U8)((mecc0>>24) & 0xff); NF_SECC_UnLock(); //解锁spare区的ECC //把main区的ECC值写入到spare区的前4个字节地址内,即第2048~2051地址 for(i=0;i<4;i++) { NF_WRDATA8(ECCBuf[i]); } NF_SECC_Lock(); //锁定spare区的ECC值 secc=rNFSECC; //读取spare区的ECC校验码 //把ECC校验码保存到全局变量数组ECCBuf中 ECCBuf[4]=(U8)(secc&0xff); ECCBuf[5]=(U8)((secc>>8) & 0xff); //把spare区的ECC值继续写入到spare区的第2052~2053地址内 for(i=4;i<6;i++) { NF_WRDATA8(ECCBuf[i]); } NF_CMD(CMD_WRITE2);//页写命令周期2 delay(1000); //延时一段时间,以等待写操作完成 NF_CMD(CMD_STATUS); //读状态命令 //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同 do{ stat = NF_RDDATA8(); }while(!(stat&0x40)); NF_nFCE_H(); //关闭Nand Flash片选 //判断状态值的第0位是否为0,为0则写操作正确,否则错误 if (stat & 0x1) { temp = rNF_MarkBadBlock(page_number>>6);//标注该页所在的块为坏块 if (temp == 0x21) return 0x43 //标注坏块失败 else return 0x44; //写操作失败 } else return 0x66; //写操作成功 } 该段程序先判断该页所在的坏是否为坏块,如果是则退出。在最后写操作失败后,还要标注该页所在的块为坏块,其中所用到的函数rNF_IsBadBlock和rNF_MarkBadBlock,我们在后面介绍。我们再总结一下该程序所返回数值的含义,0x42:表示该页所在的块为坏块;0x43:表示写操作失败,并且在标注该页所在的块为坏块时也失败;0x44:表示写操作失败,但是标注坏块成功;0x66:写操作成功。 擦除是以块为单位进行的,因此在写地址周期是,只需写三个行周期,并且要从A18开始写起。与写操作一样,在擦除结束前还要判断是否擦除操作成功,另外同样也存在需要判断是否为坏块以及要标注坏块的问题。下面就给出一段具体的块擦除操作程序: U8 rNF_EraseBlock(U32 block_number) { char stat, temp; temp = rNF_IsBadBlock(block_number); //判断该块是否为坏块 if(temp == 0x33) return 0x42; //是坏块,返回 NF_nFCE_L(); //打开片选 NF_CLEAR_RB(); //清RnB信号 NF_CMD(CMD_ERASE1); //擦除命令周期1 //写入3个地址周期,从A18开始写起 NF_ADDR((block_number < 6) & 0xff); //行地址A18~A19 NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27 NF_ADDR((block_number >> 10) & 0xff); //行地址A28 NF_CMD(CMD_ERASE2); //擦除命令周期2 delay(1000); //延时一段时间 NF_CMD(CMD_STATUS); //读状态命令 //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同 do{ stat = NF_RDDATA8(); }while(!(stat&0x40)); NF_nFCE_H(); //关闭Nand Flash片选 //判断状态值的第0位是否为0,为0则擦除操作正确,否则错误 if (stat & 0x1) { temp = rNF_MarkBadBlock(page_number>>6);//标注该块为坏块 if (temp == 0x21) return 0x43 //标注坏块失败 else return 0x44; //擦除操作失败 } else return 0x66; //擦除操作成功 } 该程序的输入参数为K9F2G08U0A的第几块,例如我们要擦除第2001块,则调用该函数为:rNF_EraseBlock(2001)。 K9F2G08U0A除了提供了页读和页写功能外,还提供了页内地址随意读、写功能。页读和页写是从页的首地址开始读、写,而随意读、写实现了在一页范围内任意地址的读、写。随意读操作是在页读操作后输入随意读命令和页内列地址,这样就可以读取到列地址所指定地址的数据。随意写操作是在页写操作的第二个页写命令周期前,输入随意写命令和页内列地址,以及要写入的数据,这样就可以把数据写入到列地址所指定的地址内。下面两段程序实现了随意读和随意写功能,其中随意读程序的输入参数分别为页地址和页内地址,输出参数为所读取到的数据,随意写程序的输入参数分别为页地址,页内地址,以及要写入的数据。 U8 rNF_RamdomRead(U32 page_number, U32 add) { NF_nFCE_L(); //打开Nand Flash片选 NF_CLEAR_RB(); //清RnB信号
S3C2440NandFlashK9F2G08U0 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)