TQ2440之nand flash读写 2020年9月18日 14:45 阅读(370) 自己写的一个nandflash读写。#include2440addr.h#includedef.h#includeNand.hS8ECCBuf[6];U32PCLK;externvoidPort_In 自己写的一个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;i for(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~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); //行地址A28 NF_CMD(CMD_READ2); //页读指令周期2 NF_DETECT_RB(); //等候RnB信号变高,即不忙 NF_CMD(CMD_RANDOMREAD1); //随意读指令周期1 //页内地址 NF_ADDR((char)(add&0xff)); //列地址A0~A7 NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11 NF_CMD(CMD_RANDOMREAD2); //随意读指令周期2 return 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~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); //行地址A28 NF_CMD(CMD_RANDOMWRITE); //随意写指令 //页内地址 NF_ADDR((char)(add&0xff)); //列地址A0~A7 NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11 NF_WRDATA8(dat); //写入数据 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) return 0x44; //失利 else return 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; //写坏块标示失利 else return 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~A19 NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27 NF_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; //擦除操作失利 } else return 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(); //复位ECC NF_MECC_UnLock(); //解锁main区的ECC NF_nFCE_L(); //翻开nandflash片选 NF_CLEAR_RB(); //清RnB信号 NF_CMD(CMD_WRITE1); //页写指令周期1 //写入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); //行地址A28 for (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; //标示坏块失利 else return 0x44; //写操作失利 } else return 0x66; //写操作成功 } U8 rNF_ReadPage( U32 page_number) { U32 i, mecc0, secc; S8 buf[2048]; NF_RSTECC(); //复位ECC NF_MECC_UnLock(); //解锁main区ECC NF_nFCE_L();//使能芯片 NF_CLEAR_RB();//铲除RnB NF_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); //行地址A28 NF_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区ECC mecc0=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; //正确 else return 0x44; //过错 } void Main(void) { S8 myid; S8 *str = “BERLIN”; Port_Init(); Uart_Select(0); Uart_Init(50000000,115200);//初始化串口 Uart_Printf(“\n\nWelcome to test nand flash!\n”); delay(100); Uart_Printf(“Now begin to init the nand flash\n”); rNF_Init();//初始化nand flash Uart_Printf(“Complete\n”); delay(100); Uart_Printf(“Now begin to reset\n”); rNF_Reset();//复位 Uart_Printf(“Complete\n”); delay(100); Uart_Printf(“Now begin to read ID\n”); myid=rNF_ReadID();//读ID Uart_Printf(“The ID is %s \n”,myid); delay(100); Uart_Printf(“Now begin to erase the nand flash\n”); rNF_EraseBlock(0); Uart_Printf(“Complete\n”);//擦除块 delay(100); Uart_Printf(“Now begin to write data to nand flash\n”); rNF_WritePage(0,*str); Uart_Printf(“Write Complete!\n”);//写页 delay(100); Uart_Printf(“Now begin to read nand flash\n”); rNF_ReadPage(0); Uart_Printf(“Complete”);//读页打印在串口 } 声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/dianzi/262564.html 标签:externvoidPort_In include2440addr includedef includeNand nandflash 为您推荐 SiC MOSFET应用技术在雪崩条件下的鲁棒性评估 电动汽车快速充电系统隔离式 DC/DC 转换器的效率最大化 桥式整流器好用 但这一点要特别注意! 河北小漫电子YANGJIE(扬杰)2SC1623-L6 15000只现货库存 用于模型飞机灯的智能开关 为什么A2B能够支持更复杂的新数据和音频传输系统