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读 评论 我来说两句…… 验证码: 相关推荐 TQ2440之nand flash读写 嵌入式系统 TQ2440nandflash读 | 2016-11-21 上一篇:关于arm-linux-gcc4.4.3在ubuntu11.10下的安装 下一篇:C程序访问ARM汇编程序中的函数 技术专区 FPGA DSP MCU 示波器 步进电机 Zigbee LabVIEW Arduino RFID NFC STM32 Protel GPS MSP430 Multisim 滤波器 CAN总线 开关电源 单片机 PCB USB ARM CPLD 连接器 MEMS CMOS MIPS EMC EDA ROM 陀螺仪 VHDL 比较器 Verilog 稳压电源 RAM AVR 传感器 可控硅 IGBT 嵌入式开发 逆变器 Quartus RS-232 Cyclone 电位器 电机控制 蓝牙 PLC PWM 汽车电子 转换器 电源管理 信号放大器 关闭
评论