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

nand flash 控制

发布时间:2020-12-15 07:14:53 所属栏目:百科 来源:网络整理
导读:? ? ? ? ? ? ? NAND?FLASH?模式配置 1.?通过NFCONF?寄存器配置NAND?Flash; 2.?写NAND?Flash?命令到NFCMMD?寄存器; 3.?写NAND?Flash?地址到NFADDR?寄存器; 4.?在读写数据时,通过NFSTAT?寄存器来获得NAND?Flash?的状态信息。应该在读操作前 或写入之后检查

?

?

?

?

?

?

?

NAND?FLASH?模式配置

1.?通过NFCONF?寄存器配置NAND?Flash;

2.?写NAND?Flash?命令到NFCMMD?寄存器;

3.?写NAND?Flash?地址到NFADDR?寄存器;

4.?在读写数据时,通过NFSTAT?寄存器来获得NAND?Flash?的状态信息。应该在读操作前

或写入之后检查R/nB?信号(准备好/忙信号)。

管脚配置

D[7:0]?:?数据/命令/地址/的输入/输出口(与数据总线共享)

CLE?:?命令锁存使能(输出)

ALE?:?地址锁存使能(输出)

nFCE?:?NAND?Flash?片选使能(输出)

nFRE?:?NAND?Flash?读使能(输出)

nFWE?:?NAND?Flash?写使能(输出)

R/nB?:?NAND?Flash?准备好/繁忙(输入)

#include"include.h"

//#include"uart.c"

extern?void?Uart_Printf(char?*fmt,...);

extern?void?Uart_Init(int?baud);

//extern?void?Uart_Select(int?ch);

/*

****************************************************************

*函数名称:InitNandCfg

*功能描述:?配置?Nandflash

*参????数:?void

*返?回?值:?void

****************************************************************

*/

static?void?InitNandCfg(void)

{

????/*命令、地址锁存持续时间HCLK,8位总线宽度*/

????rNFCONF??=?(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);

????/*不加锁,不加软锁,禁止非法访问中断,关闭忙信号变化中断,检测忙信号的上升沿

????给空余的区域ecc枷锁,*/

????rNFCONT??=?(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(0<<1);

}

static?U32?WaitNFBusy(void)

{

????U8?stat;

????

????WrNFCmd(QUERYCMD);//nand?flash?command?value

????do?{

????????stat?=?RdNFDat();?

????}

????while?(!(stat&0x40));

????WrNFCmd(READCMD0);

????return?stat&1;

}

static?U32?ReadChipId(void)

{

????U32?id,k;

????

????NFChipEn();//片选使能

??

????WrNFCmd(RdIDCMD);??//get?the?command?set?register's?value

WrNFAddr(0);???????//nand?flash?address?register?=?0

while(NFIsBusy());?//如果忙,则等待

id??=?RdNFDat()<<8;//获得rNFDATA8的数据,

????id?|=?RdNFDat();???//获得rNFDATA8的数据,并得到16位数据

NFChipDs(); ???//nand?flash?controller?disable

return?id;????????

}

static? U16?ReadStatus(void)

{

????U16?stat;

????

????NFChipEn();

????

????WrNFCmd(QUERYCMD);

????stat?=?RdNFDat();?//?get?the?rNFDATA8's?value

NFChipDs();???????//?nand?flash?controller?disable

return?stat;

}

/*------------------------------------------------------------/

函数名称: EraseBlock

功能描述: 擦除?FLASH

传????参: U32?addr

返?回?值: U32?~stat

-------------------------------------------------------------*/

U32?EraseBlock(U32?addr)

{

U8?stat;

addr?&=?~0x3f;

NFChipEn();

WrNFCmd(ERASECMD0);

WrNFAddr(addr);

WrNFAddr(addr>>8);

WrNFCmd(ERASECMD1);

stat?=?WaitNFBusy();

NFChipDs();

return?~stat;

}

/*------------------------------------------------------------/

函数名称: ReadPage

功能描述:

传????参: U32?addr,?U8?*buf

返?回?值: 无

-------------------------------------------------------------*/

void?ReadPage(U32?addr,?U8?*buf)

{

U16?i;

NFChipEn();

WrNFCmd(READCMD0);

WrNFAddr(0);

WrNFAddr(0);

WrNFAddr(addr);

WrNFAddr(addr>>8);

WrNFCmd(READCMD1);

InitEcc();

WaitNFBusy();

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

buf[i]?=?RdNFDat();

NFChipDs();

}

/*------------------------------------------------------------/

函数名称: WritePage

功能描述:

传????参: U32?addr,?U8?*buf

返?回?值: U32?~stat

-------------------------------------------------------------*/

U32?WritePage(U32?addr,?U8?*buf)

{

U32?i,?mecc;

U8?stat,?tmp[7];

NFChipEn();

WrNFCmd(PROGCMD0);

WrNFAddr(0);

WrNFAddr(0);

WrNFAddr(addr);

WrNFAddr(addr>>8);

InitEcc(); //reset?mecc?and?secc

MEccUnlock();

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

WrNFDat(buf[i]);

MEccLock();

mecc?=?RdNFMEcc());

tmp[0]?=?mecc&0xff;

????tmp[1]?=?(mecc>>8)&0xff;

????tmp[2]?=?(mecc>>16)&0xff;

????tmp[3]?=?(mecc>>24)&0xff;

????tmp[5]?=?0xff; //mark?good?block

?

WrNFDat(0xff);//2048,坏块标志

SEccUnlock();

WrNFDat(tmp[0]);//ECC校验码

WrNFDat(tmp[1]);

WrNFDat(tmp[2]);

WrNFDat(tmp[3]);

SEccLock();

WrNFCmd(PROGCMD1);

stat?=?WaitNFBusy();

NFChipDs();

return?~stat;

}

/*------------------------------------------------------------/

函数名称: nandMain

功能描述: 入口函数

传????参: 无

返?回?值: 无

-------------------------------------------------------------*/

void?nand_Main(void)?

{?

U16?ID,i;?

U8?buf[512];?

U32?NFBlockNO=6;?

U32?NFPagesNO?=?25;?

U32?status;?

U32?BlockPages;

BlockPages?=(NFBlockNO<<6)+NFPagesNO;?

Uart_Init(115200);?

Uart_Printf("nthe?main?is?runningn");?

InitNandCfg();????????????//初始化函数

ID=ReadChipId();//ID=ECf1?

Uart_Printf("nnand?flash`s?ID?is:%xn",ID);?

??

????if(EraseBlock(BlockPages)&0x1==TRUE)?

????{???

Uart_Printf("nblock?%d?is?erasedn",NFBlockNO);?

ReadPage(BlockPages,buf);?

Uart_Printf("n/***********************擦除之后flash中的数据?****************/n");?

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

???????? Uart_Printf("%4x",?buf[i]);?

????????

Uart_Printf("n/***********************应写入数据****************/n");?

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

{?

buf[i]?=?i;?

Uart_Printf("%4x",?buf[i]);???

?? ?? }?

?? ??

?????? Uart_Printf("nWrite?data[%d?block,?%d?page].n",?NFBlockNO,NFPagesNO);?

?????? status?=?WritePage(BlockPages,buf);??

???????

????? if(status&0x1==TRUE?)???

?????? Uart_Printf("nWrite?OK.n");?

?????? else???

?????? Uart_Printf("nWrite?Error.n");

????????

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

???????? buf[i]?=?1;?????????//为验证后边数组中的数据是来自flash

????????

?????????????

????? ReadPage(BlockPages,buf);?

????? Uart_Printf("nRead?data[%d?block,NFPagesNO);?

?????

????????Uart_Printf("n/***********************?读出的数据?****************/n");?

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

???????? Uart_Printf("%4x",?buf[i]);?

????}

????

else

Uart_Printf("nblock?%4x?erased?is?badn",NFBlockNO);?

while(1);?

}

再给主程序命名的时候一定不能够带?"_"?不然会找不到入口的main函数,以为是语法错误,结果才是文件名不对。

(编辑:李大同)

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

    推荐文章
      热点阅读