S3C2440對(duì)Nand_Flash的基本操作_第1頁(yè)
S3C2440對(duì)Nand_Flash的基本操作_第2頁(yè)
S3C2440對(duì)Nand_Flash的基本操作_第3頁(yè)
S3C2440對(duì)Nand_Flash的基本操作_第4頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余11頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、精品文檔S3C2440對(duì) Nand Flash操作和電路原理 K9F2G08U0AS3C2440 內(nèi)部集成了一個(gè)Nand flash控制器。 S3C2440 的 Nand flash控制器包含了如下的特性:l 一個(gè)引導(dǎo)啟動(dòng)單元lNand Flash 存儲(chǔ)器接口,支持8 位或 16 位的每頁(yè)大小為 256 字, 512 字節(jié), 1K字和 2K 字節(jié)的 Nand flashl軟件模式:用戶可以直接訪問(wèn)Nand Flash 存儲(chǔ)器,此特性可以用于 Nand Flash存儲(chǔ)器的讀、擦除和編程。lS3C2440 支持 8/16 位的 Nand Flash 存儲(chǔ)器接口總線l硬件 ECC 生成,檢測(cè)和指示

2、(軟件糾錯(cuò) )。lSteppingstone 接口,支持大 /小端模式的按字節(jié) /半字 /字訪問(wèn)。我用的開(kāi)發(fā)板是天嵌的TQ2440 ,板子用到的 Nand Flash 是 Samsung 公司的 K9F2G08U0A ,它是 8 位的 Nand flash 。本文只介紹 Nand Flash 的電路原理和 Nand Flash 的讀、寫(xiě)、擦除等基本操作,暫不涉及Nand Flash 啟動(dòng)程序的問(wèn)題。Nand Flash 的電路連接如圖1 所示:圖 1 Nand Flash 電路原理上圖的左邊為 K9F2G08U0A與 2440 的連接圖,原理方面就不多介紹,去看看datasheet 估計(jì)就懂得

3、了,右邊的部分是 S3C2440 的 Nand 控制器的配置。配置引腳NCON ,GPG13 ,GPG14 和 GPG15 用來(lái)設(shè)置 Nand Flash 的基本信息, Nand 控制器通過(guò)讀取配置引腳的狀態(tài)獲取外接的Nand Flash 的配置信息,圖2 是這四個(gè)配置引腳的定義:.精品文檔圖 2 Nand 控制配置引腳信息由于 K9F2G08U0A 的總線寬度為 8 位,頁(yè)大小為 2048 字節(jié),需要 5 個(gè)尋址命令,所以 NCON 、GPG13 和 GPG14應(yīng)該接高電平, GPG15 應(yīng)該接低電平。K9F2G08U0A 沒(méi)有地址或數(shù)據(jù)總線,只有8 個(gè) IO 口,這 8 個(gè) IO 口用于傳

4、輸命令、地址和數(shù)據(jù)。K9F2G08U0A主要以 page (頁(yè))為單位進(jìn)行讀寫(xiě),以block (塊)為單位進(jìn)行擦除。每一頁(yè)中又分為main 區(qū)和 spare 區(qū), main 區(qū)用于正常數(shù)據(jù)的存儲(chǔ), spare 區(qū)用于存儲(chǔ)一些附加信息,如塊好壞的標(biāo)記、塊的邏輯地址、頁(yè)內(nèi)數(shù)據(jù)的ECC 校驗(yàn)和等。K9F2G08U0A 的存儲(chǔ)陣列如圖3 所示:圖 3 K9F2G08U0A 內(nèi)部存儲(chǔ)陣列由上圖,我們可以知道: K9F2G08U0A 的一頁(yè)為(2K 64)字節(jié)(2K 表示的是 main 區(qū)容量, 64 表示的是 spare 區(qū)容量),它的一塊為 64 頁(yè),而整個(gè)設(shè)備包括了 2048 個(gè)塊。這樣算下來(lái)一共有

5、 2112M 位容量,如果只算 main 區(qū)容量則有 256M 字節(jié)(即 256M× 8 位)。圖 4 K9F2G08U0A地址序列.精品文檔要實(shí)現(xiàn)用 8 個(gè) IO 口來(lái)要訪問(wèn)這么大的容量,如圖4 所示:K9F2G08U0A規(guī)定了用 5 個(gè)周期來(lái)實(shí)現(xiàn)。第一個(gè)周期訪問(wèn)的地址為 A0A7 ;第二個(gè)周期訪問(wèn)的地址為A8A11 ,它作用在 IO0IO3 上,而此時(shí) IO4IO7 必須為低電平;第三個(gè)周期訪問(wèn)的地址為A12A19 ;第四個(gè)周期訪問(wèn)的地址為A20A27 ;第五個(gè)周期訪問(wèn)的地址為A28 ,它作用在 IO0上,而此時(shí) IO1IO7 必須為低電平。前兩個(gè)周期傳輸?shù)氖橇械刂?,后三個(gè)周期傳

6、輸?shù)氖切械刂?。通過(guò)分析可知,列地址是用于尋址頁(yè)內(nèi)空間,行地址用于尋址頁(yè),如果要直接訪問(wèn)塊,則需要從地址A18 開(kāi)始。由于所有的命令、地址和數(shù)據(jù)全部從 8 位 IO 口傳輸,所以 Nand flash 定義了一個(gè)命令集來(lái)完成各種操作。有的操作只需要一個(gè)命令(即一個(gè)周期)即可,而有的操作則需要兩個(gè)命令(即兩個(gè)周期)來(lái)實(shí)現(xiàn)。K9F2G08U0A 的命令說(shuō)明如圖5 所示:圖 5 K9F2G08U0A 命令表為了方便使用,我們宏定義了 K9F2G08U0A 的常用命令#define CMD_READ10x00/ 頁(yè)讀命令周期 1#define CMD_READ20x30/ 頁(yè)讀命令周期 2#define

7、 CMD_READID0x90/讀 ID 命令#define CMD_WRITE10x80/頁(yè)寫(xiě)命令周期 1#define CMD_WRITE20x10/頁(yè)寫(xiě)命令周期 2#define CMD_ERASE10x60/塊擦除命令周期 1#define CMD_ERASE20xd0/塊擦除命令周期 2#define CMD_STATUS0x70/讀狀態(tài)命令#define CMD_RESET0xff/ 復(fù)位#define CMD_RANDOMREAD10x05/ 隨意讀命令周期 1.精品文檔#define CMD_RANDOMREAD20xE0/ 隨意讀命令周期 2#define CMD_RANDO

8、MWRITE0x85/隨意寫(xiě)命令接下來(lái)介紹幾個(gè) Nand Flash 控制器的寄存器。 Nand Flash 控制器的寄存器主要有 NFCONF (Nand Flash 配置寄存器), NFCONT (Nand Flash 控制寄存器), NFCMMD (Nand Flash 命令集寄存器), NFADDR (Nand Flash 地址集寄存器),NFDATA(Nand Flash 數(shù)據(jù)寄存器),NFMECCD0/1 (Nand Flash 的 main 區(qū) ECC 寄存器),NFSECCD( Nand Flash 的 spare 區(qū) ECC 寄存器), NFSTAT (Nand Flash

9、操作狀態(tài)寄存器), NFESTAT0/1 (Nand Flash 的ECC 狀態(tài)寄存器), NFMECC0/1 (Nand Flash 用于數(shù)據(jù)的 ECC 寄存器),以及 NFSECC (Nand Flash 用于 IO 的 ECC 寄存器)。( 1)NFCONF:2440 的 NFCONF 寄存器是用來(lái)設(shè)置 NAND Flash 的時(shí)序參數(shù) TACLS 、TWRPH0 、TWRPH1 。配置寄存器的 3:0是只讀位,用來(lái)指示外部所接的Nand Flash 的配置信息,它們是由配置引腳NCON ,GPG13 ,GPG14和 GPG15 所決定的(比如說(shuō) K9F2G08U0A 的配置為 NCON

10、 、GPG13 和 GPG14 接高電平, GPG15 接低電平,所以3:0 位狀態(tài)應(yīng)該是 1110 )。(2)NFCONT :用來(lái)使能 /禁止 NAND Flash 控制器、使能 /禁止控制引腳信號(hào)nFCE 、初始化 ECC 。它還有其他功能,在一般的應(yīng)用中用不到,比如鎖定NAND Flash 。(3)NFCMMD :對(duì)于不同型號(hào)的Flash ,操作命令一般不一樣。參考前面介紹的K9F2G08U0A 命令序列。( 4)NFADDR: 當(dāng)寫(xiě)這個(gè)寄存器時(shí),它將對(duì) Flash 發(fā)出地址信號(hào)。只用到低 8 位來(lái)傳輸,所以需要分次來(lái)寫(xiě)入一個(gè)完整的 32 位地址, K9F2G08U0A 的地址序列在圖

11、4 已經(jīng)做了詳細(xì)說(shuō)明。(5)NFDATA: 只用到低 8 位,讀、寫(xiě)此寄存器將啟動(dòng)對(duì)NAND Flash 的讀數(shù)據(jù)、寫(xiě)數(shù)據(jù)操作。( 6)NFSTAT: 只用到位 0,用來(lái)檢測(cè) NAND 是否準(zhǔn)備好。 0:busy ,1:ready 。NFCONF 寄存器使用 TACLS 、TWRPH0 、TWRPH1 這 3 個(gè)參數(shù)來(lái)控制 NAND Flash 信號(hào)線 CLE/ALE 與寫(xiě)控制信號(hào) nWE 的時(shí)序關(guān)系,它們之間的關(guān)系如圖 6 和圖 7 所示:圖 6 CLE/ALE 時(shí)序圖.精品文檔圖 7 nWE 和 nRE 時(shí)序圖TACLS 為 CLE/ALE 有效到 nWE 有效之間的持續(xù)時(shí)間, TWRPH

12、0 為 nWE 的有效持續(xù)時(shí)間, TWRPH1 為 nWE無(wú)效到 CLE/ALE 無(wú)效之間的持續(xù)時(shí)間,這些時(shí)間都是以HCLK 為單位的。通過(guò)查閱K9F2G08U0A 的數(shù)據(jù)手冊(cè),我們可以找到并計(jì)算與S3C2440 相對(duì)應(yīng)的時(shí)序: K9F2G08U0A 中的 Twp 與 TWRPH0 相對(duì)應(yīng), Tclh 與 TWRPH1 相對(duì)應(yīng),TACLS 應(yīng)該是與 Tcls 相對(duì)應(yīng)。 K9F2G08U0A給出的都是最小時(shí)間,2440 只要滿足它的最小時(shí)間即可。TACLS 、TWRPH0 、TWRPH1 這三個(gè)變量取值大一些會(huì)更保險(xiǎn),在這里,這三個(gè)值分別取1,2 和 0。下面就開(kāi)始詳細(xì)介紹K9F2G08U0A

13、的基本操作,包括復(fù)位,讀ID,頁(yè)讀、寫(xiě)數(shù)據(jù),隨意讀、寫(xiě)數(shù)據(jù),塊擦除等。為了更好地應(yīng)用 ECC和使能 Nand Flash 片選,我們還需要一些宏定義:#define NF_nFCE_L()rNFCONT &= (1<<1); #define NF_CE_L()NF_nFCE_L() /打開(kāi) nandflash 片選#define NF_nFCE_H()rNFCONT |= (1<<1); #define NF_CE_H()NF_nFCE_H()/ 關(guān)閉 nandflash 片選#define NF_RSTECC()rNFCONT |= (1<<4);

14、 / 復(fù)位 ECC#define NF_MECC_UnLock() rNFCONT &= (1<<5); /解鎖 main 區(qū) ECC#define NF_MECC_Lock()rNFCONT |= (1<<5); /鎖定 main 區(qū) ECC#define NF_SECC_UnLock()rNFCONT &= (1<<6); / 解鎖 spare 區(qū) ECC#define NF_SECC_Lock()rNFCONT |= (1<<6); /鎖定 spare 區(qū) ECCNFSTAT 是另一個(gè)比較重要的寄存器,它的第0 位可以用于判

15、斷 nandflash 是否在忙,第2 位用于檢測(cè) RnB 引腳信號(hào):#define NF_WAITRB()while(!(rNFSTAT &(1<<0) ) ); / 等待 Nand Flash 不忙.精品文檔#define NF_CLEAR_RB() rNFSTAT |= (1<<2); /清除 RnB 信號(hào)#define NF_DETECT_RB()while(!(rNFSTAT&(1<<2);/等待 RnB 信號(hào)變高,即不忙NFCMMD ,NFADDR 和 NFDATA 分別用于傳輸命令,地址和數(shù)據(jù),為了方便起見(jiàn),我們可以定義一些宏定

16、義用于完成上述操作:#define NF_CMD(data)rNFCMD= (data); / 傳輸命令#define NF_ADDR(addr)rNFADDR = (addr); /傳輸?shù)刂?define NF_RDDATA()(rNFDATA)/ 讀 32 位數(shù)據(jù)#define NF_RDDATA8()(rNFDATA8)/讀8位數(shù)據(jù)#define NF_WRDATA(data)rNFDATA = (data); /寫(xiě) 32 位數(shù)據(jù)#define NF_WRDATA8(data)rNFDATA8 = (data); / 寫(xiě)8位數(shù)據(jù)首先,是初始化操作void rNF_Init(void)rN

17、FCONF = (TACLS<<12)|(TWRPH0<<8)|( TWRPH1<<4)|(0<<0);/初始化時(shí)序參數(shù)rNFCONT =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);/非鎖定,屏蔽 nandflash 中斷,初始化 ECC 及鎖定 main 區(qū)和 spare 區(qū) ECC ,使能 nandflash 控制器,禁止片

18、選rNF_Reset();/ 復(fù)位芯片復(fù)位操作,寫(xiě)入復(fù)位命令static void rNF_Reset()NF_CE_L();/打開(kāi) nandflash 片選NF_CLEAR_RB();/清除 RnB 信號(hào)NF_CMD(CMD_RESET);/ 寫(xiě)入復(fù)位命令.精品文檔NF_DETECT_RB();/等待 RnB 信號(hào)變高,即不忙NF_CE_H();/關(guān)閉 nandflash 片選讀取 K9F2G08U0A 芯片 ID 的操作如下: 時(shí)序圖在 datasheet 的 figure18 。首先需要寫(xiě)入讀 ID 命令 (0x90) ,然后再寫(xiě)入 0x00 地址,并等待芯片就緒,就可以讀取到一共五個(gè)周

19、期的芯片 ID ,第一個(gè)周期為廠商 ID ,第二個(gè)周期為設(shè)備 ID,第三個(gè)周期至第五個(gè)周期包括了一些具體的該芯片信息,函數(shù)如下static char rNF_ReadID()char pMID;char pDID;char cyc3, cyc4, cyc5;NF_nFCE_L();/打開(kāi) nandflash 片選NF_CLEAR_RB();/清 RnB 信號(hào)NF_CMD(CMD_READID);/讀 ID 命令NF_ADDR(0x0);/寫(xiě) 0x00 地址for ( i = 0; i < 100; i+ ); 等一段時(shí)間/讀五個(gè)周期的 IDpMID = NF_RDDATA8();/廠商

20、ID:0xECpDID = NF_RDDATA8();/設(shè)備 ID:0xDAcyc3 = NF_RDDATA8();/0x10cyc4 = NF_RDDATA8();/0x95cyc5 = NF_RDDATA8();/0x44NF_nFCE_H();/關(guān)閉 nandflash片選return (pDID);.精品文檔下面介紹 Nand Flash讀操作 ,讀操作是以頁(yè)為單位進(jìn)行的。如果在讀取數(shù)據(jù)的過(guò)程中不進(jìn)行ECC 校驗(yàn)判斷,則讀操作比較簡(jiǎn)單,在寫(xiě)入讀命令的兩個(gè)周期之間寫(xiě)入要讀取的頁(yè)地址,然后讀取數(shù)據(jù)即可。如果為了更準(zhǔn)確地讀取數(shù)據(jù),則在讀取完數(shù)據(jù)之后還要進(jìn)行 ECC 校驗(yàn)判斷,以確定所讀取的數(shù)

21、據(jù)是否正確。在上文中已經(jīng)介紹過(guò), Nand Flash 的每一頁(yè)有兩區(qū): main 區(qū)和 spare 區(qū), main 區(qū)用于存儲(chǔ)正常的數(shù)據(jù),spare 區(qū)用于存儲(chǔ)其他附加信息,其中就包括 ECC 校驗(yàn)碼。當(dāng)我們?cè)趯?xiě)入數(shù)據(jù)的時(shí)候,我們就計(jì)算這一頁(yè)數(shù)據(jù)的ECC 校驗(yàn)碼,然后把校驗(yàn)碼存儲(chǔ)到 spare 區(qū)的特定位置中,在下次讀取這一頁(yè)數(shù)據(jù)的時(shí)候,同樣我們也計(jì)算ECC 校驗(yàn)碼,然后與 spare區(qū)中的 ECC 校驗(yàn)碼比較,如果一致則說(shuō)明讀取的數(shù)據(jù)正確,如果不一致則不正確。ECC 的算法較為復(fù)雜,好在 S3C2440 能夠硬件產(chǎn)生 ECC 校驗(yàn)碼,這樣就省去了不少的麻煩事。 S3C2440 既可以產(chǎn)生

22、main 區(qū)的 ECC 校驗(yàn)碼,也可以產(chǎn)生 spare 區(qū)的 ECC 校驗(yàn)碼。因?yàn)?K9F2G08U0A是 8 位 IO 口,因此 S3C2440共產(chǎn)生 4個(gè)字節(jié)的 main 區(qū) ECC 碼和 2 個(gè)字節(jié)的 spare 區(qū) ECC 碼。在這里我們規(guī)定,在每一頁(yè)的spare 區(qū)的第 0 個(gè)地址到第 3個(gè)地址存儲(chǔ) main 區(qū) ECC ,第 4 個(gè)地址和第 5 個(gè)地址存儲(chǔ) spare 區(qū) ECC 。產(chǎn)生 ECC 校驗(yàn)碼的過(guò)程為:在讀取或?qū)懭肽膫€(gè)區(qū)的數(shù)據(jù)之前,先解鎖該區(qū)的ECC ,以便產(chǎn)生該區(qū)的 ECC 。在讀取或?qū)懭胪陻?shù)據(jù)之后,再鎖定該區(qū)的 ECC ,這樣系統(tǒng)就會(huì)把產(chǎn)生的 ECC 碼保存到相應(yīng)的寄

23、存器中。 main 區(qū)的 ECC 保存到 NFMECC0/1 中(因?yàn)?K9F2G08U0A 是 8 位 IO 口,因此這里只用到了 NFMECC0 ), spare 區(qū)的 ECC 保存到NFSECC 中。對(duì)于讀操作來(lái)說(shuō),我們還要繼續(xù)讀取spare 區(qū)的相應(yīng)地址內(nèi)容,以得到上次寫(xiě)操作時(shí)所存儲(chǔ)的main 區(qū)和spare 區(qū)的 ECC ,并把這些數(shù)據(jù)分別放入 NFMECCD0/1 和 NFSECCD 的相應(yīng)位置中。最后我們就可以通過(guò)讀取 NFESTAT0/1 (因?yàn)?K9F2G08U0A 是 8 位 IO 口,因此這里只用到了 NFESTAT0 )中的低 4 位來(lái)判斷讀取的數(shù)據(jù)是否正確,其中第 0

24、 位和第 1 位為 main 區(qū)指示錯(cuò)誤,第 2 位和第 3 位為 spare 區(qū)指示錯(cuò)誤。下面是一段具體的頁(yè)讀操 作程序:U8 rNF_ReadPage( U32 page_number )U32 i, mecc0, secc;NF_RSTECC();/復(fù)位 ECCNF_MECC_UnLock();/ 解鎖 main 區(qū) ECCNF_nFCE_L();/使能芯片NF_CLEAR_RB();/清除 RnBNF_CMD(CMD_READ1);/頁(yè)讀命令周期1, 0x00/寫(xiě)入 5 個(gè)地址周期NF_ADDR(0x00);/ 列地址 A0-A7NF_ADDR(0x00);/列地址 A8-A11NF_

25、ADDR(page_number) & 0xff);/行地址 A12-A19NF_ADDR(page_number >> 8) & 0xff);/ 行地址 A20-A27NF_ADDR(page_number >> 16) & 0xff);/行地址 A28NF_CMD(CMD_READ2);/ 頁(yè)讀命令周期2, 0x30NF_DETECT_RB();/等待 RnB 信號(hào)變高,即不忙.精品文檔for (i = 0; i < 2048; i+)bufi =NF_RDDATA8();/讀取一頁(yè)數(shù)據(jù)內(nèi)容NF_MECC_Lock();/ 鎖定 mai

26、n 區(qū) ECC 值NF_SECC_UnLock();/ 解鎖 spare 區(qū) ECC/讀 spare 區(qū)的前 4 個(gè)地址內(nèi)容,即第20482051 地址,這4 個(gè)字節(jié)為main 區(qū)的 ECCmecc0=NF_RDDATA();/把讀取到的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(

27、);/ 鎖定 spare 區(qū)的 ECC 值/繼續(xù)讀 spare 區(qū)的 4 個(gè)地址內(nèi)容, 即第 20522055 地址,其中前 2 個(gè)字節(jié)為spare區(qū)的ECC 值secc=NF_RDDA TA();/把讀取到的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;/ 錯(cuò)誤這段

28、程序是把某一頁(yè)的內(nèi)容讀取到全局變量數(shù)組 buffer 中。該程序的輸入?yún)?shù)直接就為 K9F2G08U0A 的第幾頁(yè),例如我們要讀取第 128064 頁(yè)中的內(nèi)容,可以調(diào)用該程序?yàn)椋?rNF_ReadPage(128064) 。由于第 128064 頁(yè)是第 2001塊中的第 0 頁(yè)(128064 2001×640),所以為了更清楚地表示頁(yè)與塊之間的關(guān)系,也可以寫(xiě)為:rNF_ReadPage(2001*64) 。頁(yè)寫(xiě)操作的大致流程為:在兩個(gè)寫(xiě)命令周期之間分別寫(xiě)入頁(yè)地址和數(shù)據(jù),當(dāng)然如果為了保證下次讀取該數(shù)據(jù)時(shí)的正確性,還需要把 main 區(qū)的 ECC 值和 spare 區(qū)的 ECC 值寫(xiě)入到

29、該頁(yè)的 spare 區(qū)內(nèi)。然后我們還需要讀取狀態(tài)寄存器,以判斷這次寫(xiě)操作是否正確。下面就給出一段具體的頁(yè)寫(xiě)操作程序,其中輸入?yún)?shù)也是要寫(xiě)入數(shù)據(jù)到第幾頁(yè):U8 rNF_WritePage(U32 page_number).精品文檔U32 i, mecc0, secc;U8 stat, temp;temp = rNF_IsBadBlock(page_number>>6);/判斷該塊是否為壞塊if(temp = 0x33)return 0x42;/是壞塊,返回NF_RSTECC();/復(fù)位 ECC >使能 ECCNF_MECC_UnLock();/解鎖 main 區(qū)的 ECCNF_

30、nFCE_L();/ 打開(kāi) nandflash 片選NF_CLEAR_RB();/清 RnB 信號(hào)NF_CMD(CMD_WRITE1);/ 頁(yè)寫(xiě)命令周期1/寫(xiě)入 5 個(gè)地址周期NF_ADDR(0x00);/列地址 A0A7NF_ADDR(0x00);/ 列地址 A8A11NF_ADDR(page_number) & 0xff);/行地址 A12A19NF_ADDR(page_number >> 8) & 0xff);/行地址 A20A27NF_ADDR(page_number >> 16) & 0xff);/行地址 A28for (i = 0;

31、i < 2048; i+)/寫(xiě)入一頁(yè)數(shù)據(jù)NF_WRDATA8(char)(i+6);NF_MECC_Lock();/ 鎖定 main 區(qū)的 ECC 值mecc0=rNFMECC0;/讀取 main 區(qū)的 ECC 校驗(yàn)碼/把 ECC 校驗(yàn)碼由字型轉(zhuǎn)換為字節(jié)型,并保存到全局變量數(shù)組ECCBuf 中ECCBuf0=(U8)(mecc0&0xff);ECCBuf1=(U8)(mecc0>>8) & 0xff);ECCBuf2=(U8)(mecc0>>16) & 0xff);ECCBuf3=(U8)(mecc0>>24) & 0x

32、ff);NF_SECC_UnLock();/ 解鎖 spare 區(qū)的 ECC/把 main 區(qū)的 ECC 值寫(xiě)入到spare 區(qū)的前 4 個(gè)字節(jié)地址內(nèi),即第20482051 地址for(i=0;i<4;i+)NF_WRDATA8(ECCBufi);NF_SECC_Lock();/鎖定 spare 區(qū)的 ECC 值secc=rNFSECC;/讀取 spare 區(qū)的 ECC 校驗(yàn)碼/把 ECC 校驗(yàn)碼保存到全局變量數(shù)組ECCBuf 中ECCBuf4=(U8)(secc&0xff);ECCBuf5=(U8)(secc>>8) & 0xff);/把 spare 區(qū)的

33、ECC 值繼續(xù)寫(xiě)入到spare 區(qū)的第 20522053 地址內(nèi)for(i=4;i<6;i+).精品文檔NF_WRDATA8(ECCBufi);NF_CMD(CMD_WRITE2);/頁(yè)寫(xiě)命令周期2delay(1000);/ 延時(shí)一段時(shí)間,以等待寫(xiě)操作完成NF_CMD(CMD_STA TUS);/ 讀狀態(tài)命令/判斷狀態(tài)值的第6 位是否為1,即是否在忙,該語(yǔ)句的作用與NF_DETECT_RB(); 相同dostat = NF_RDDATA8();while(!(stat&0x40);NF_nFCE_H();/關(guān)閉 Nand Flash 片選/判斷狀態(tài)值的第0 位是否為0,為 0 則

34、寫(xiě)操作正確,否則錯(cuò)誤if (stat & 0x1)temp = rNF_MarkBadBlock(page_number>>6);/標(biāo)注該頁(yè)所在的塊為壞塊if (temp = 0x21)return 0x43/ 表示寫(xiě)操作失敗,并且在標(biāo)注該頁(yè)所在的塊為壞塊時(shí)也失敗elsereturn 0x44;/ 寫(xiě)操作失敗elsereturn 0x66;/ 寫(xiě)操作成功該段程序先判斷該頁(yè)所在的壞是否為壞塊,如果是則退出。在最后寫(xiě)操作失敗后,還要標(biāo)注該頁(yè)所在的塊為壞塊,其中所用到的函數(shù)rNF_IsBadBlock 和 rNF_MarkBadBlock ,我們?cè)诤竺娼榻B。我們?cè)倏偨Y(jié)一下該程序所

35、返回?cái)?shù)值的含義, 0x42:表示該頁(yè)所在的塊為壞塊;0x43:表示寫(xiě)操作失敗,并且在標(biāo)注該頁(yè)所在的塊為壞塊時(shí)也失??;0x44:表示寫(xiě)操作失敗,但是標(biāo)注壞塊成功;0x66:寫(xiě)操作成功。擦除 是以塊為單位進(jìn)行的,因此在寫(xiě)地址周期是,只需寫(xiě)三個(gè)行周期,并且要從A18 開(kāi)始寫(xiě)起。與寫(xiě)操作一樣,在擦除結(jié)束前還要判斷是否擦除操作成功,另外同樣也存在需要判斷是否為壞塊以及要標(biāo)注壞塊的問(wèn)題。下面就給出一段具體的塊擦除操作程序:U8 rNF_EraseBlock(U32 block_number)char stat, temp;temp = rNF_IsBadBlock(block_number); / 判斷該

36、塊是否為壞塊 if(temp = 0x33)return 0x42;/是壞塊,返回NF_nFCE_L();/打開(kāi)片選NF_CLEAR_RB();/ 清 RnB 信號(hào)NF_CMD(CMD_ERASE1);/ 擦除命令周期1/ 寫(xiě)入 3 個(gè)地址周期,從A18 開(kāi)始寫(xiě)起.精品文檔NF_ADDR(block_number << 6) & 0xff);/行地址 A18A19NF_ADDR(block_number >> 2) & 0xff);/行地址 A20A27NF_ADDR(block_number >> 10) & 0xff);/行地址

37、A28NF_CMD(CMD_ERASE2);/擦除命令周期2delay(1000);/延時(shí)一段時(shí)間NF_CMD(CMD_STATUS);/讀狀態(tài)命令/判斷狀態(tài)值的第6 位是否為1,即是否在忙,該語(yǔ)句的作用與NF_DETECT_RB(); 相同dostat = NF_RDDA TA8();while(!(stat&0x40);NF_nFCE_H();/關(guān)閉 Nand Flash 片選/判斷狀態(tài)值的第0 位是否為0,為 0 則擦除操作正確,否則錯(cuò)誤if (stat & 0x1)temp = rNF_MarkBadBlock(page_number>>6); / 標(biāo)注該塊

38、為壞塊 if (temp = 0x21)return 0x43/標(biāo)注壞塊失敗elsereturn 0x44;/擦除操作失敗elsereturn 0x66;/ 擦除操作成功該程序的輸入?yún)?shù)為K9F2G08U0A 的第幾塊,例如我們要擦除第2001 塊,則調(diào)用該函數(shù)為: rNF_EraseBlock(2001)K9F2G08U0A 除了提供了頁(yè)讀和頁(yè)寫(xiě)功能外,還提供了頁(yè)內(nèi)地址隨意讀、寫(xiě)功能。頁(yè)讀和頁(yè)寫(xiě)是從頁(yè)的首地址開(kāi)始讀、寫(xiě),而隨意讀、寫(xiě)實(shí)現(xiàn)了在一頁(yè)范圍內(nèi)任意地址的讀、寫(xiě)。隨意讀操作是在頁(yè)讀操作后輸入隨意讀命令和頁(yè)內(nèi)列地址,這樣就可以讀取到列地址所指定地址的數(shù)據(jù)。隨意寫(xiě)操作是在頁(yè)寫(xiě)操作的第二個(gè)頁(yè)寫(xiě)

39、命令周期前,輸入隨意寫(xiě)命令和頁(yè)內(nèi)列地址,以及要寫(xiě)入的數(shù)據(jù),這樣就可以把數(shù)據(jù)寫(xiě)入到列地址所指定的地址內(nèi)。下面兩段程序?qū)崿F(xiàn)了隨意讀和隨意寫(xiě)功能,其中隨意讀程序的輸入?yún)?shù)分別為頁(yè)地址和頁(yè)內(nèi)地址,輸出參數(shù)為所讀取到的數(shù)據(jù),隨意寫(xiě)程序的輸入?yún)?shù)分別為頁(yè)地址,頁(yè)內(nèi)地址,以及要寫(xiě)入的數(shù)據(jù)。U8 rNF_RamdomRead(U32 page_number, U32 add)NF_nFCE_L();/打開(kāi) Nand Flash 片選NF_CLEAR_RB();/清 RnB 信號(hào)NF_CMD(CMD_READ1);/頁(yè)讀命令周期1/寫(xiě)入 5 個(gè)地址周期NF_ADDR(0x00);/列地址 A0A7NF_ADDR

40、(0x00);/列地址 A8A11NF_ADDR(page_number) & 0xff);/行地址 A12A19NF_ADDR(page_number >> 8) & 0xff);/行地址 A20A27.精品文檔NF_ADDR(page_number >> 16) & 0xff);/行地址 A28NF_CMD(CMD_READ2);/頁(yè)讀命令周期 2NF_DETECT_RB();/ 等待 RnB 信號(hào)變高,即不忙NF_CMD(CMD_RANDOMREAD1);/ 隨意讀命令周期 1/頁(yè)內(nèi)地址NF_ADDR(char)(add&0xff);/列地址 A0A7NF_ADDR(char)(add>>8)&0x0f);

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論