TQ2440之nand flash讀寫 作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 加入技術(shù)交流群 掃碼加入和技術(shù)大咖面對面交流海量資料庫查詢 收藏 自己寫的一個nand flash讀寫。#include"2440addr.h"#include"def.h"#include"Nand.h"S8 ECCBuf[6];U32 PCLK;extern void Port_Init(void);//以下四個函數(shù)在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();//以下三個函數(shù)在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//頁內(nèi)地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_CMD(CMD_RANDOMREAD2); //隨意讀命令周期2return NF_RDDATA8(); //讀取數(shù)據(jù)}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); //隨意寫命令//頁內(nèi)地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_WRDATA8(dat); //寫入數(shù)據(jù)NF_CMD(CMD_WRITE2); //頁寫命令周期2delay(1000); //延時一段時間NF_CMD(CMD_STATUS); //讀狀態(tài)命令//判斷狀態(tài)值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同do{ stat = NF_RDDATA8();}while(!(stat&0x40));NF_nFCE_H(); //關(guān)閉Nand Flash片選//判斷狀態(tài)值的第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; //寫壞塊標(biāo)注失敗elsereturn 0x60; //寫壞塊標(biāo)注成功}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); //讀狀態(tài)命令 //判斷狀態(tài)值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同NF_DETECT_RB();NF_nFCE_H(); //關(guān)閉Nand Flash片選//判斷狀態(tài)值的第0位是否為0,為0則擦除操作正確,否則錯誤if (stat & 0x1){ temp = rNF_MarkBadBlock(block_number); //標(biāo)注該塊為壞塊 if (temp == 0x21) return 0x43; //標(biāo)注壞塊失敗 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(); //復(fù)位ECCNF_MECC_UnLock(); //解鎖main區(qū)的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++)//寫入一頁數(shù)據(jù){NF_WRDATA8(mydata);i += 6;Uart_Printf("n test %s",mydata);}NF_MECC_Lock(); //鎖定main區(qū)的ECC值mecc0=rNFMECC0; //讀取main區(qū)的ECC校驗(yàn)碼//把ECC校驗(yàn)碼由字型轉(zhuǎn)換為字節(jié)型,并保存到全局變量數(shù)組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區(qū)的ECC//把main區(qū)的ECC值寫入到spare區(qū)的前4個字節(jié)地址內(nèi),即第2048~2051地址for(i=0;i<4;i++){NF_WRDATA8(ECCBuf[i]);}NF_SECC_Lock(); //鎖定spare區(qū)的ECC值secc=rNFSECC; //讀取spare區(qū)的ECC校驗(yàn)碼//把ECC校驗(yàn)碼保存到全局變量數(shù)組ECCBuf中ECCBuf[4]=(U8)(secc&0xff);ECCBuf[5]=(U8)((secc>>8) & 0xff);//把spare區(qū)的ECC值繼續(xù)寫入到spare區(qū)的第2052~2053地址內(nèi)for(i=4;i<6;i++){NF_WRDATA8(ECCBuf[i]);} NF_CMD(CMD_WRITE2); //頁寫命令周期2 delay(1000); //延時一段時間,以等待寫操作完成NF_CMD(CMD_STATUS); //讀狀態(tài)命令//判斷狀態(tài)值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同do{stat = NF_RDDATA8();}while(!(stat&0x40));NF_nFCE_H(); //關(guān)閉Nand Flash片選//判斷狀態(tài)值的第0位是否為0,為0則寫操作正確,否則錯誤if (stat & 0x1){temp = rNF_MarkBadBlock(page_number>>6);//標(biāo)注該頁所在的塊為壞塊if (temp == 0x21)return 0x43; //標(biāo)注壞塊失敗elsereturn 0x44; //寫操作失敗}elsereturn 0x66; //寫操作成功}U8 rNF_ReadPage( U32 page_number){ U32 i, mecc0, secc; S8 buf[2048];NF_RSTECC(); //復(fù)位ECCNF_MECC_UnLock(); //解鎖main區(qū)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();//讀取一頁數(shù)據(jù)內(nèi)容 Uart_Printf("%s",buf[i]); }NF_MECC_Lock(); //鎖定main區(qū)ECC值NF_SECC_UnLock(); //解鎖spare區(qū)ECCmecc0=NF_RDDATA(); //讀spare區(qū)的前4個地址內(nèi)容,即第2048~2051地址,這4個字節(jié)為main區(qū)的ECC //把讀取到的main區(qū)的ECC校驗(yàn)碼放入NFMECCD0/1的相應(yīng)位置內(nèi)rNFMECCD0=((mecc0&0xff00)<<8)|(mecc0&0xff);rNFMECCD1=((mecc0&0xff000000)>>8)|((mecc0&0xff0000)>>16);NF_SECC_Lock(); //鎖定spare區(qū)的ECC值secc=NF_RDDATA(); //繼續(xù)讀spare區(qū)的4個地址內(nèi)容,即第2052~2055地址,其中前2個字節(jié)為spare區(qū)的ECC值 //把讀取到的spare區(qū)的ECC校驗(yàn)碼放入NFSECCD的相應(yīng)位置內(nèi)rNFSECCD=((secc&0xff00)<<8)|(secc&0xff); NF_nFCE_H(); //關(guān)閉nandflash片選 //判斷所讀取到的數(shù)據(jù)是否正確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();//復(fù)位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");//讀頁打印在串口} 關(guān)鍵詞: TQ2440nandflash讀 評論 我來說兩句…… 驗(yàn)證碼: 相關(guān)推薦 TQ2440之nand flash讀寫 嵌入式系統(tǒng) TQ2440nandflash讀 | 2016-11-21 上一篇:關(guān)于arm-linux-gcc4.4.3在ubuntu11.10下的安裝 下一篇:C程序訪問ARM匯編程序中的函數(shù) 技術(shù)專區(qū) FPGA DSP MCU 示波器 步進(jìn)電機(jī) Zigbee LabVIEW Arduino RFID NFC STM32 Protel GPS MSP430 Multisim 濾波器 CAN總線 開關(guān)電源 單片機(jī) PCB USB ARM CPLD 連接器 MEMS CMOS MIPS EMC EDA ROM 陀螺儀 VHDL 比較器 Verilog 穩(wěn)壓電源 RAM AVR 傳感器 可控硅 IGBT 嵌入式開發(fā) 逆變器 Quartus RS-232 Cyclone 電位器 電機(jī)控制 藍(lán)牙 PLC PWM 汽車電子 轉(zhuǎn)換器 電源管理 信號放大器 關(guān)閉
評論