TQ2440之nand flash讀寫(xiě) 作者: 時(shí)間:2016-11-21 來(lái)源:網(wǎng)絡(luò ) 加入技術(shù)交流群 掃碼加入和技術(shù)大咖面對面交流海量資料庫查詢(xún) 收藏 自己寫(xiě)的一個(gè)nand flash讀寫(xiě)。#include"2440addr.h"#include"def.h"#include"Nand.h"S8 ECCBuf[6];U32 PCLK;extern void Port_Init(void);//以下四個(gè)函數在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();//以下三個(gè)函數在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(); //打開(kāi)Nand Flash片選NF_CLEAR_RB(); //清RnB信號NF_CMD(CMD_READ1); //頁(yè)讀命令周期1//寫(xiě)入5個(gè)地址周期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); //頁(yè)讀命令周期2NF_DETECT_RB(); //等待RnB信號變高,即不忙NF_CMD(CMD_RANDOMREAD1); //隨意讀命令周期1//頁(yè)內地址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(); //打開(kāi)Nand Flash片選NF_CLEAR_RB(); //清RnB信號NF_CMD(CMD_WRITE1); //頁(yè)寫(xiě)命令周期1//寫(xiě)入5個(gè)地址周期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); //隨意寫(xiě)命令//頁(yè)內地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_WRDATA8(dat); //寫(xiě)入數據NF_CMD(CMD_WRITE2); //頁(yè)寫(xiě)命令周期2delay(1000); //延時(shí)一段時(shí)間NF_CMD(CMD_STATUS); //讀狀態(tài)命令//判斷狀態(tài)值的第6位是否為1,即是否在忙,該語(yǔ)句的作用與NF_DETECT_RB();相同do{ stat = NF_RDDATA8();}while(!(stat&0x40));NF_nFCE_H(); //關(guān)閉Nand Flash片選//判斷狀態(tài)值的第0位是否為0,為0則寫(xiě)操作正確,否則錯誤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; //寫(xiě)壞塊標注失敗elsereturn 0x60; //寫(xiě)壞塊標注成功}U8 rNF_EraseBlock(U32 block_number){char stat, temp;temp = rNF_IsBadBlock(block_number); //判斷該塊是否為壞塊if(temp == 0x33)return 0x42; //是壞塊,返回NF_nFCE_L(); //打開(kāi)片選NF_CLEAR_RB(); //清RnB信號NF_CMD(CMD_ERASE1); //擦除命令周期1 //寫(xiě)入3個(gè)地址周期,從A18開(kāi)始寫(xiě)起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); //延時(shí)一段時(shí)間 NF_CMD(CMD_STATUS); //讀狀態(tài)命令 //判斷狀態(tài)值的第6位是否為1,即是否在忙,該語(yǔ)句的作用與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); //標注該塊為壞塊 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(); //打開(kāi)nandflash片選NF_CLEAR_RB(); //清RnB信號NF_CMD(CMD_WRITE1); //頁(yè)寫(xiě)命令周期1 //寫(xiě)入5個(gè)地址周期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++)//寫(xiě)入一頁(yè)數據{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值寫(xiě)入到spare區的前4個(gè)字節地址內,即第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值繼續寫(xiě)入到spare區的第2052~2053地址內for(i=4;i<6;i++){NF_WRDATA8(ECCBuf[i]);} NF_CMD(CMD_WRITE2); //頁(yè)寫(xiě)命令周期2 delay(1000); //延時(shí)一段時(shí)間,以等待寫(xiě)操作完成NF_CMD(CMD_STATUS); //讀狀態(tài)命令//判斷狀態(tài)值的第6位是否為1,即是否在忙,該語(yǔ)句的作用與NF_DETECT_RB();相同do{stat = NF_RDDATA8();}while(!(stat&0x40));NF_nFCE_H(); //關(guān)閉Nand Flash片選//判斷狀態(tài)值的第0位是否為0,為0則寫(xiě)操作正確,否則錯誤if (stat & 0x1){temp = rNF_MarkBadBlock(page_number>>6);//標注該頁(yè)所在的塊為壞塊if (temp == 0x21)return 0x43; //標注壞塊失敗elsereturn 0x44; //寫(xiě)操作失敗}elsereturn 0x66; //寫(xiě)操作成功}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); //頁(yè)讀命令周期1,0x00 //寫(xiě)入5個(gè)地址周期 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); //頁(yè)讀命令周期2,0x30 NF_DETECT_RB(); ////等待RnB信號變高,即不忙 for (i = 0; i < 2048; i++) { buf[i] = NF_RDDATA8();//讀取一頁(yè)數據內容 Uart_Printf("%s",buf[i]); }NF_MECC_Lock(); //鎖定main區ECC值NF_SECC_UnLock(); //解鎖spare區ECCmecc0=NF_RDDATA(); //讀spare區的前4個(gè)地址內容,即第2048~2051地址,這4個(gè)字節為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個(gè)地址內容,即第2052~2055地址,其中前2個(gè)字節為spare區的ECC值 //把讀取到的spare區的ECC校驗碼放入NFSECCD的相應位置內rNFSECCD=((secc&0xff00)<<8)|(secc&0xff); NF_nFCE_H(); //關(guān)閉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");//寫(xiě)頁(yè)delay(100);Uart_Printf("Now begin to read nand flashn");rNF_ReadPage(0);Uart_Printf("Complete");//讀頁(yè)打印在串口} 關(guān)鍵詞: TQ2440nandflash讀 評論 我來(lái)說(shuō)兩句…… 驗證碼: 相關(guān)推薦 TQ2440之nand flash讀寫(xiě) 嵌入式系統 TQ2440nandflash讀 | 2016-11-21 上一篇:關(guān)于arm-linux-gcc4.4.3在ubuntu11.10下的安裝 下一篇:C程序訪(fǎng)問(wèn)ARM匯編程序中的函數 技術(shù)專(zhuān)區 FPGA DSP MCU 示波器 步進(jìn)電機 Zigbee LabVIEW Arduino RFID NFC STM32 Protel GPS MSP430 Multisim 濾波器 CAN總線(xiàn) 開(kāi)關(guān)電源 單片機 PCB USB ARM CPLD 連接器 MEMS CMOS MIPS EMC EDA ROM 陀螺儀 VHDL 比較器 Verilog 穩壓電源 RAM AVR 傳感器 可控硅 IGBT 嵌入式開(kāi)發(fā) 逆變器 Quartus RS-232 Cyclone 電位器 電機控制 藍牙 PLC PWM 汽車(chē)電子 轉換器 電源管理 信號放大器 關(guān)閉 国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
評論