nand flash 控制
来源:互联网 发布:javs编程思想pdf百度云 编辑:程序博客网 时间:2024/06/07 12:58
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 running\n");
InitNandCfg(); //初始化函数
ID=ReadChipId();//ID=ECf1
Uart_Printf("\nnand flash`s ID is:%x\n",ID);
if(EraseBlock(BlockPages)&0x1==TRUE)
{
Uart_Printf("\nblock %d is erased\n",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, %d page].\n", NFBlockNO,NFPagesNO);
Uart_Printf("\n/*********************** 读出的数据 ****************/\n");
for(i=0; i<512; i++)
Uart_Printf("%4x", buf[i]);
}
else
Uart_Printf("\nblock %4x erased is bad\n",NFBlockNO);
while(1);
}
再给主程序命名的时候一定不能够带 "_" 不然会找不到入口的main函数,以为是语法错误,结果才是文件名不对。
- nand flash 控制
- FPGA 控制 nand flash读写
- STM32使用FSMC控制NAND flash 例程
- Nand Flash
- NAND Flash
- nand flash
- NAND FLASH
- NAND FLASH
- nand flash
- Nand Flash
- NAND Flash
- NAND FLASH
- nand flash
- nand flash
- Nand flash
- NAND FLASH
- NAND FLASH
- NAND Flash
- Paip.YXSHOP易想商场功能模块说明
- 小米2012新品发布会(小米手机2),8月16日
- 广搜:Knights Move
- 距离
- 第十二天——Second Quiz
- nand flash 控制
- 深搜:Nightmare
- ios自定义checkbox
- Set3
- lazyLoad 懒加载 图片例子
- ubuntu nautilus ./ 以窗口模式打开当前目录
- ordinal parameter mismatch
- 爱你却不能牵你的手
- 线段树模板 (poj 3468)延迟标记