TQ2440之nand flash读写 嵌入式系统 时间:2016-11-21来源:网络 自己写的一个nand flash读写。#include"2440addr.h"#include"def.h"#include"Nand.h"S8 ECCBuf[6];U32 PCLK;extern void Port_Init(void);//以下四个函数在2440lib.c中extern void Uart_Select(int ch);extern void Uart_Init(int pclk,int baud);extern void Uart_Printf(char *fmt,...);extern void rNF_Reset();//以下三个函数在nand.c中extern void rNF_Init(void);extern char rNF_ReadID();void delay(U32 time){U32 i,j;for(i=0;ifor(j=0;j<1000;j++);}U8 rNF_RamdomRead(U32 page_number, U32 add){NF_nFCE_L(); //打开Nand Flash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_READ1); //页读命令周期1//写入5个地址周期NF_ADDR(0x00); //列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff); //行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_READ2); //页读命令周期2NF_DETECT_RB(); //等待RnB信号变高,即不忙NF_CMD(CMD_RANDOMREAD1); //随意读命令周期1//页内地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_CMD(CMD_RANDOMREAD2); //随意读命令周期2return NF_RDDATA8(); //读取数据}U8 rNF_RamdomWrite(U32 page_number, U32 add, U8 dat){U8 stat;NF_nFCE_L(); //打开Nand Flash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_WRITE1); //页写命令周期1//写入5个地址周期NF_ADDR(0x00); //列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff); //行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_RANDOMWRITE); //随意写命令//页内地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_WRDATA8(dat); //写入数据NF_CMD(CMD_WRITE2); //页写命令周期2delay(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)return 0x44; //失败elsereturn 0x66; //成功}U8 rNF_IsBadBlock(U32 block){ return rNF_RamdomRead(block*64, 2054);}U8 rNF_MarkBadBlock(U32 block){U8 result;result = rNF_RamdomWrite(block*64, 2054, 0x33); if(result == 0x44)return 0x21; //写坏块标注失败elsereturn 0x60; //写坏块标注成功}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~A19NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27NF_ADDR((block_number >> 10) & 0xff); //行地址A28 NF_CMD(CMD_ERASE2); //擦除命令周期2 delay(100); //延时一段时间 NF_CMD(CMD_STATUS); //读状态命令 //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同NF_DETECT_RB();NF_nFCE_H(); //关闭Nand Flash片选//判断状态值的第0位是否为0,为0则擦除操作正确,否则错误if (stat & 0x1){ temp = rNF_MarkBadBlock(block_number); //标注该块为坏块 if (temp == 0x21) return 0x43; //标注坏块失败 else return 0x44; //擦除操作失败}elsereturn 0x66; //擦除操作成功}U8 rNF_WritePage(U32 page_number,S8 mydata){U32 i, mecc0, secc;U8 stat, temp;temp = rNF_IsBadBlock(page_number>>6); //判断该块是否为坏块if(temp == 0x33)return 0x42; //是坏块,返回NF_RSTECC(); //复位ECCNF_MECC_UnLock(); //解锁main区的ECCNF_nFCE_L(); //打开nandflash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_WRITE1); //页写命令周期1 //写入5个地址周期NF_ADDR(0x00); //列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff); //行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28for (i = 0; i < 2048; i++)//写入一页数据{NF_WRDATA8(mydata);i += 6;Uart_Printf("n test %s",mydata);}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; //标注坏块失败elsereturn 0x44; //写操作失败}elsereturn 0x66; //写操作成功}U8 rNF_ReadPage( U32 page_number){ U32 i, mecc0, secc; S8 buf[2048];NF_RSTECC(); //复位ECCNF_MECC_UnLock(); //解锁main区ECC NF_nFCE_L();//使能芯片 NF_CLEAR_RB();//清除RnBNF_CMD(CMD_READ1); //页读命令周期1,0x00 //写入5个地址周期 NF_ADDR(0x00); //列地址A0-A7 NF_ADDR(0x00); //列地址A8-A11 NF_ADDR((page_number) & 0xff); //行地址A12-A19 NF_ADDR((page_number >> 8) & 0xff); //行地址A20-A27 NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_READ2); //页读命令周期2,0x30 NF_DETECT_RB(); ////等待RnB信号变高,即不忙 for (i = 0; i < 2048; i++) { buf[i] = NF_RDDATA8();//读取一页数据内容 Uart_Printf("%s",buf[i]); }NF_MECC_Lock(); //锁定main区ECC值NF_SECC_UnLock(); //解锁spare区ECCmecc0=NF_RDDATA(); //读spare区的前4个地址内容,即第2048~2051地址,这4个字节为main区的ECC //把读取到的main区的ECC校验码放入NFMECCD0/1的相应位置内rNFMECCD0=((mecc0&0xff00)<<8)|(mecc0&0xff);rNFMECCD1=((mecc0&0xff000000)>>8)|((mecc0&0xff0000)>>16);NF_SECC_Lock(); //锁定spare区的ECC值secc=NF_RDDATA(); //继续读spare区的4个地址内容,即第2052~2055地址,其中前2个字节为spare区的ECC值 //把读取到的spare区的ECC校验码放入NFSECCD的相应位置内rNFSECCD=((secc&0xff00)<<8)|(secc&0xff); NF_nFCE_H(); //关闭nandflash片选 //判断所读取到的数据是否正确if((rNFESTAT0 & 0xf) == 0x0)return 0x66; //正确elsereturn 0x44; //错误}void Main(void){S8 myid;S8 *str = "BERLIN"; Port_Init();Uart_Select(0);Uart_Init(50000000,115200);//初始化串口Uart_Printf("nnWelcome to test nand flash!n");delay(100);Uart_Printf("Now begin to init the nand flashn");rNF_Init();//初始化nand flashUart_Printf("Completen");delay(100);Uart_Printf("Now begin to resetn");rNF_Reset();//复位Uart_Printf("Completen");delay(100);Uart_Printf("Now begin to read IDn");myid=rNF_ReadID();//读IDUart_Printf("The ID is %s n",myid);delay(100);Uart_Printf("Now begin to erase the nand flashn");rNF_EraseBlock(0);Uart_Printf("Completen");//擦除块delay(100);Uart_Printf("Now begin to write data to nand flashn");rNF_WritePage(0,*str);Uart_Printf("Write Complete!n");//写页delay(100);Uart_Printf("Now begin to read nand flashn");rNF_ReadPage(0);Uart_Printf("Complete");//读页打印在串口} 关键词: TQ2440nandflash读 阅读全文 加入微信获取电子行业最新资讯搜索微信公众号:EEPW或用微信扫描左侧二维码 相关文章 TQ2440之nand flash读写 嵌入式系统 2016-11-21 查看电脑版