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); //讀狀態(tài)命令//判斷狀態(tài)值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同do{ stat = NF_RDDATA8();}while(!(stat&0x40));NF_nFCE_H(); //關閉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; //寫壞塊標注失敗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); //讀狀態(tài)命令 //判斷狀態(tài)值的第6位是否為1,即是否在忙,該語句的作用與NF_DETECT_RB();相同NF_DETECT_RB();NF_nFCE_H(); //關閉Nand Flash片選//判斷狀態(tài)值的第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區(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++)//寫入一頁數據{NF_WRDATA8(mydata);i += 6;Uart_Printf("n test %s",mydata);}NF_MECC_Lock(); //鎖定main區(qū)的ECC值mecc0=rNFMECC0; //讀取main區(qū)的ECC校驗碼//把ECC校驗碼由字型轉換為字節(jié)型,并保存到全局變量數組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é)地址內,即第2048~2051地址for(i=0;i<4;i++){NF_WRDATA8(ECCBuf[i]);}NF_SECC_Lock(); //鎖定spare區(qū)的ECC值secc=rNFSECC; //讀取spare區(qū)的ECC校驗碼//把ECC校驗碼保存到全局變量數組ECCBuf中ECCBuf[4]=(U8)(secc&0xff);ECCBuf[5]=(U8)((secc>>8) & 0xff);//把spare區(qū)的ECC值繼續(xù)寫入到spare區(qū)的第2052~2053地址內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(); //關閉Nand Flash片選//判斷狀態(tài)值的第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區(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();//讀取一頁數據內容 Uart_Printf("%s",buf[i]); }NF_MECC_Lock(); //鎖定main區(qū)ECC值NF_SECC_UnLock(); //解鎖spare區(qū)ECCmecc0=NF_RDDATA(); //讀spare區(qū)的前4個地址內容,即第2048~2051地址,這4個字節(jié)為main區(qū)的ECC //把讀取到的main區(qū)的ECC校驗碼放入NFMECCD0/1的相應位置內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個地址內容,即第2052~2055地址,其中前2個字節(jié)為spare區(qū)的ECC值 //把讀取到的spare區(qū)的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讀寫 嵌入式系統(tǒng) TQ2440nandflash讀 | 2016-11-21 上一篇:關于arm-linux-gcc4.4.3在ubuntu11.10下的安裝 下一篇:C程序訪問ARM匯編程序中的函數 技術專區(qū) 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 穩(wěn)壓電源 RAM AVR 傳感器 可控硅 IGBT 嵌入式開發(fā) 逆變器 Quartus RS-232 Cyclone 電位器 電機控制 藍牙 PLC PWM 汽車電子 轉換器 電源管理 信號放大器 關閉
評論