加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

对NandFlash编程实现的代码进行分析

发布时间:2020-12-15 17:32:28 所属栏目:百科 来源:网络整理
导读:整个程序段分解为四个部分来分析,初始化NandFlash,读取NandFlash的ID号,NandFlash块擦洗,NandFlash的页数据读写; 在对代码进行分析之前需要把代码中的相应常量定义先列出来: #define ? EnNandFlash()? (rNFCONF |= 0x8000) //bit15=1 enable NANDflash

整个程序段分解为四个部分来分析,初始化NandFlash,读取NandFlash的ID号,NandFlash块擦洗,NandFlash的页数据读写;

在对代码进行分析之前需要把代码中的相应常量定义先列出来:

#define ? EnNandFlash()? (rNFCONF |= 0x8000) //bit15=1 enable NANDflash controller

#define????NFChipEn()????????(rNFCONF?&=?~0x800)?//bit11=0Nandflash nFCE = L (active)

#define????EnNandFlash()????(rNFCONF?|=?0x8000)?//bit15=1enable NAND flash controller
#define????DsNandFlash()????(rNFCONF?&=?~0x8000)?//bit15=1disable NAND flash controller
#define????InitEcc()????????(rNFCONF?|=?0x1000)?//bit12=1initialize ECC
#define????NoEcc()????????????(rNFCONF?&=?~0x1000)?//bit12=0initialize ECC
#define????NFChipEn()????????(rNFCONF?&=?~0x800)?//bit11=0NAND flash nFCE = L (active)
#define????NFChipDs()????????(rNFCONF?|=?0x800)?//bit11=1NAND flash nFCE = H (inactive)
#define????WrNFCmd(cmd)????(rNFCMD?=?(cmd))?//writecommond to nand flash
#define????WrNFAddr(addr)????(rNFADDR?=?(addr))?//writeaddress to nand flash
#define????WrNFDat(dat)????(rNFDATA?=?(dat))?//writedata to nand flash
#define????RdNFDat()????????(rNFDATA)?//readdata from nand flash
#define????RdNFStat()????????(rNFSTAT)?//readstatus from nand flash
#define????NFIsBusy()????????(!(rNFSTAT&1))?//whethernand flash is busy?
#define????NFIsReady()????????(rNFSTAT&1)?//whethernand flash is ready?
#define????READCMD0????0?//Read0model command == Page addr 0~127
#define????READCMD1????1?//Read1model command == Page addr 128~511
#define????READCMD2????0x50?//Read2model command == Page addr 512~527
#define????ERASECMD0????0x60?//Blockerase command 0
#define????ERASECMD1????0xd0?//Blockerase command 1
#define????PROGCMD0????0x80?//pagewrite command 0
#define????PROGCMD1????0x10?//pagewrite command 1
#define????QUERYCMD????0x70?//querycommand
#define????RdIDCMD????????0x90?//readid command

一、初始化NandFlash

初始化部分对NandFlash的控制寄存器进行初始化配置,而rNFCONF是NandFlash的配置寄存器;在初始化部分的代码基本上所以的Flash都可以公用的。

//****?? 初始化? K9F1208U0M nand flash??? ****/

staticvoid InitNandCfg(void)

{

????? //enablenand flash control,initilize ecc,chip disable,

rNFCONF =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7);

//对NandFlash的控制寄存器进行初始化配置,rNFCONF是NandFlash的配置寄存器

//使用控制器,使用ECC,不激活NandFlash,持续时间都设置为HCLK*8

}

二、读NandFlash的ID号

/****? K9F1208U0M nand flash? 的ID? ****/

staticU32 ReadChipId(void)

{

U32 id;

?

NFChipEn(); ????????????????????? //选中NandFlash

WrNFCmd(RdIDCMD); ???? //写入90h指令,这是读 ID的命令

WrNFAddr(0); ?????????????????? //写入地址00h

while(NFIsBusy());? ?????????? //等待前一步完成

id? =RdNFDat()<<8; ??????? //8位的NandFlash,之前定义过RdNFDat()

id |= RdNFDat();?? ???? ?????? //读DeviceCode

NFChipDs();??

return id;

}

三、NandFlash 块擦除

**? K9F1208U0M nand flash? 的块擦除操作? ****/

staticU32 EraseBlock(U32 addr)

{

U8 stat;

?

addr &= ~0x1f; ????????????????? //保留9-25位

?

NFChipEn();?????????????????? //芯片使能,片选拉低,Nand Flash使能

WrNFCmd(ERASECMD0); //擦出的启动指令为60h

WrNFAddr(addr); ??????????? //写入块地址1

WrNFAddr(addr>>8); ???????? //块地址2

if(NandAddr) ?????????? ????????? //判断Flash的型号

WrNFAddr(addr>>16); ????? //后传A17-A24,A25

WrNFCmd(ERASECMD1); //发出擦出命令0Xd0H

stat = WaitNFBusy(); ??????? //写完擦除命令后,执行等待过程

NFChipDs(); ??????? ????????????? //失能

return stat; ????????? ????????????? //返回到star

}

四、NandFlash的写、读操作

对于NandFlash而言,地址和命令只能在I/O[7:0]上传递,数据宽度为8位;由于地址只能在I/O[7:0]上传递,因此必须采用移位的方式进行。

写操作的过程为:

/****? K9F1208U0M nand flash? 的页数据写? ****/

staticU32 WritePage(U32 addr,U8 *buf)

{

U16 i;

U8 stat,tmp[3];

NFChipEn(); ????????????? ?????? //使能NandFlash

WrNFCmd(PROGCMD0); ?? //写入串行数据输入指令(80h)

WrNFAddr(0);?????? ???? ?????? ?????? //写地址,即为第1个cycle

WrNFAddr(addr); ?????? ?????? //写地址的第2个cycle

WrNFAddr(addr>>8);?????????? //写地址的第3个cycle

if(NandAddr)

WrNFAddr(addr>>16); ?????? //写地址的第4个cycle

InitEcc();????????????????????????? //初始化ECC检测

for(i=0; i<512; i++)

WrNFDat(buf[i]); ?????? //循环写入1页数据

?

tmp[0] = rNFECC0; ?????????? //产生3位校验码

tmp[1] = rNFECC1;

tmp[2] = rNFECC2;

?

WrNFDat(tmp[0]); ???????????? //将校验码写入页面

WrNFDat(tmp[1]);

WrNFDat(tmp[2]);

?

WrNFCmd(PROGCMD1); ?? //正是开始写入数据

stat = WaitNFBusy();

NFChipDs();

?

if(stat)

printf("Write nand flash 0x%xfailn",addr);

else {

U8 RdDat[512];

? ?????????? ReadPage(addr,RdDat);??

? ?????????? for(i=0;i<512; i++)

?? ??????????????? if(RdDat[i]!=buf[i]){

??????? ????????????? printf("Checkdata at page 0x%x,offset 0x%x failn",addr,i);

?? ???????? ???????????? stat= 1;

??? ???????????????????? break;

?? ??????????????? }

}

return stat;?

}

读操作的过程为:

/****? K9F1208U0M nand flash? 的页数据读? ****/

staticvoid ReadPage(U32 addr,U8 *buf)???? //addr= page address 即是Flashd地址

{

U16 i;

NFChipEn(); ????????????????????? //使能NandFlash

?

WrNFCmd(READCMD0); ? //发送读指令‘0x00’,整页读取

WrNFAddr(0);??????????????????????????? //读地址的第1个cycle, 读一个Page,addr=0

WrNFAddr(addr); ?????????????? //读地址的第2个cycle,即A[9:16]

WrNFAddr(addr>>8); ???????? //读地址的第3个cycle,即A[17:24]

if(NandAddr)

WrNFAddr(addr>>16); ?????? //读地址的第4个cycle,即A[25]。

InitEcc(); ?????????????????????????? //初始化ECC

WaitNFBusy(); ??????????? ?????? //等待系统不忙

for(i=0; i<512; i++)

buf[i] = RdNFDat(); ?? //循环读出1页数据

NFChipDs(); ??????????????????? //释放NandFlash

}?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读