arm9-s3c2440——nandflash读写

最近课程在学习nandflash读写,分享一下代码,希望可以给大家一些思路
nandflash的读写需要根据实际的flash型号来操作,遇到问题要学会看datasheet,我使用的mini2440,板上是256M SAMSUNG的K9F2G08U0C,nandflash的存储结构是256M分为2048个块,每个块128k,每一块有上下分为64页,每一页2k,我们在读写时写入32位地址即可。

地址的读写分为5个周期,每个周期写入的地址规则如下
在这里插入图片描述

在写入前需要擦除flash上的数据,nandflash的擦除是以块为单位的,即只要写入块地址,即上表中提到的行地址。在实际过程中,擦除操作可能会操作失败,因此我使用状态机的方式,擦除失败后继续当前得擦除操作直到擦除成功。代码如下:

U8 nandflash_test()
{
	//500k = 128k*3+2k*58
	//由于从0开始算 500k的地址应该在第3块,第57页的首地址处0x7D000
	//0x0007d000 =0000 0000 0000 0111 1101 0000 0000 0000
	U32 add = 0x7d000;
	U8 step=0;
	U8 wbuf[2048]={0};
	U8 rbuf[2048]={0};
	U32 i=0;
	U8 stat;
	while(1)
	{
		switch (step)
		{
			case 0: //准备要写入的数据
				Uart_Printf("准备要写入的数据\n");
				Uart_Printf("this is write data \n");
				for(i=0;i<20;i++)
				{
					wbuf[i]=i&0xff;
					Uart_Printf("第 %d 个数据:%d\n",i,wbuf[i]);
				}
				step++;
				break;
			case 1://初始化nandflash
				Uart_Printf("初始化nandflash\n");
				Nand_Init();
				step++;
				break;
			case 2://擦除要写入的整个块区
				Uart_Printf("擦除要写入的整个块区\n");
				//add &=~0x3f;
				nandflash_enable();
				nandflash_cmd(0x60);
				NF_ADDR((add>>12)&0xff);//A19-A12 = 0111 1101
  				NF_ADDR((add>>20)&0xff);//A27-A20 = 0000 0000
  				NF_ADDR((add>>28)&0xff)//A28 = 0000 0000 
				//nandflash_addr(add);//A18-A19
				//nandflash_addr(add>>8);//A20-A27
				//nandflash_addr(add>>16);//A28
				nandflash_cmd(0xd0);
				do{
 					 stat=NF_RDDATA8();
  				}while(!(stat&0x40));
 				NF_nFCE_H();//控制芯片使能拉高  
  				if(stat&0x1)
  				{
  					Uart_Printf("clean lose\n");
  					break;
  				}
				else 
				{
					Uart_Printf(" clearn successful \n");
					step++;
					break;
				}	
			case 3://向目标地址写入数据
				Uart_Printf("向目标地址写入数据\n");
			 	Nand_Reset();
 				NF_RSTECC();  
  				NF_MECC_UnLock();
  				NF_nFCE_L();
  				NF_CLEAR_RB();
 				NF_CMD(0x80);						
  				//总共五个传递周期
  				NF_ADDR(0x00);//A7-A0 = 0000 0000
 				NF_ADDR(0x00); //A10-A8 = 0000 0000
  				NF_ADDR((add>>12)&0xff);//A19-A12 = 0111 1101
  				NF_ADDR((add>>20)&0xff);//A27-A20 = 0000 0000
  				NF_ADDR((add>>28)&0xff)//A28 = 0000 0000 
				for (i = 0; i < 20; i++) 
					rNFDATA8 = wbuf[i];				
 				NF_CMD(0x10);	//发送写结束指令 
  				NF_nFCE_H();//控制芯片使能拉高  
 				Uart_Printf("write successfully\n");
				step++;
				break;
			case 4://读取写入的数据  
				Uart_Printf("读取写入的数据\n");
	 			Nand_Reset();
			 	NF_nFCE_L();
			 	NF_CLEAR_RB();
			 	NF_CMD(0x00);						// Read command
  			 	NF_ADDR(0x00);//A7-A0 = 0000 0000
 				NF_ADDR(0&0x00); //A10-A8 = 0000 0000
  				NF_ADDR((add>>12)&0xff);//A19-A12 = 0111 1101
  				NF_ADDR((add>>20)&0xff);//A27-A20 = 0000 0000
  				NF_ADDR((add>>28)&0xff)//A28 = 0000 0000 
	  		 	NF_CMD(0x30);	//发送写结束指令
   			 	NF_DETECT_RB();//等待系统不忙 
  			 	for (i = 0; i < 20; i++)
			    	rbuf[i] = rNFDATA8;
			 	NF_nFCE_H();//控制芯片使能拉高  
			 	step++;
			 	break;
			 case 5:
			 	Uart_Printf("\r\n this is read data \r\n");
			 	for(i=0;i<20;i++)
			 	{
			 		rbuf[i]=i&0xff;
			 		Uart_Printf("第 %d 个数据:%d\n",i,rbuf[i]);
			 	}
			 	return 1;
			 	
		}
	}
		
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值