找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 11645|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

怎么看時(shí)序圖--nand flash的讀操作詳解

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:65608 發(fā)表于 2014-9-12 01:10 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

這篇文章不是介紹 nand flash的物理結(jié)構(gòu)和關(guān)于nand flash的一些基本知識(shí)的。你需要至少了解 你手上的 nand flash的物理結(jié)構(gòu)和一些諸如讀寫(xiě)命令

        操作的大概印象,你至少也需要看過(guò) s3c2440中關(guān)于nand flash控制寄存器的說(shuō)明。


        由于本人也沒(méi)有專(zhuān)門(mén)學(xué)過(guò)這方面的知識(shí),下面的介紹也是經(jīng)驗(yàn)之談。

        這里 我用的 K9F2G08-SCB0 這款nand flash 來(lái)介紹時(shí)序圖的閱讀。不同的芯片操作時(shí)序可能不同,讀的命令也會(huì)有一些差別。

        當(dāng)然其實(shí)有時(shí)候像nand flash這種 s3c2440內(nèi)部集成了他的控制器的外設(shè)。具體到讀寫(xiě)操作的細(xì)節(jié)時(shí)序(比如 CLE/ALE的建立時(shí)間,寫(xiě)脈沖的寬度。數(shù)據(jù)的建立和保持時(shí)間等),不明白前期也沒(méi)有多大的問(wèn)題。

        因?yàn)閟3c2440內(nèi)部的nand flash控制器 做了大部分的工作,你需要做的基本就是設(shè)置 幾個(gè)時(shí)間參數(shù)而已。然后nand flash會(huì)自動(dòng)進(jìn)行這些細(xì)節(jié)操作。

        當(dāng)然如果處理器上沒(méi)有集成 nand flash的控制器 那么久必須要自己來(lái)寫(xiě)時(shí)序操作了。所以了解最底層的時(shí)序操作總是好的

         

        但是上層一點(diǎn)的,比如讀寫(xiě)操作的步驟時(shí)序(比如讀操作,你要片選使能,然后發(fā)命令,然后發(fā)地址,需要的話還需發(fā)一個(gè)命令,然后需要等待操作完成,然后再讀書(shū)數(shù)據(jù))。

        是必須要明白的。這都不明白的話,怎么進(jìn)行器件的操作呢

         

        也就是說(shuō) s3c2440 可以說(shuō)在你設(shè)置很少的幾個(gè)時(shí)間參數(shù)后,將每一個(gè)步驟中 細(xì)微的操作都替你做好了。(比如寫(xiě)命令,你只要寫(xiě)個(gè)命令到相應(yīng)寄存器中,cpu內(nèi)部就會(huì)協(xié)各個(gè)引腳發(fā)出

        適應(yīng)的信號(hào)來(lái)實(shí)現(xiàn)寫(xiě)命令的操作)。

        而我們所需要做的 就是 把這些寫(xiě)命令,寫(xiě)地址,等待操作完成。等步驟組合起來(lái) 。從而完成一個(gè) 讀操作

         

        就像上面說(shuō)的,雖然我們不會(huì)需要去編寫(xiě)每個(gè) 步驟中的最細(xì)微的時(shí)序。 但是了解下。會(huì)讓你對(duì)每個(gè)操作步驟的底層細(xì)節(jié)更加明了

         

        先來(lái)看一個(gè)命令鎖存的時(shí)序。也就是上面說(shuō)的 讀 nand flash操作中不是有一個(gè) 寫(xiě)命令步驟嗎。那么這個(gè)步驟具體是怎么實(shí)現(xiàn)的。

        首先 我們肯定是要片選 nand flash。只有選中芯片才能讓他工作啊

        nand flash是通過(guò) ALE/CLE (高電平有效)來(lái)區(qū)分?jǐn)?shù)據(jù)線上的數(shù)據(jù)時(shí)命令(CLE有效),地址(ALE有效)還是數(shù)據(jù)(CLE/ALE都無(wú)效)。

        那么這里既然是寫(xiě)命令 那么就一定是 CLE有效(高電平) ALE無(wú)效(低電平)。

        同樣命令既然是寫(xiě)給nand flash的那么 肯定有一個(gè)寫(xiě)周期。我們需要注意的是,寫(xiě)是在上升沿有效還是下降沿有效。

        時(shí)序圖如下:

        1 這里是命令鎖存是時(shí)序,那么我們要注意的其實(shí)就只有 CLE 為高電平期間這段時(shí)序。(寫(xiě)命令啊,CLE有效時(shí)(高電平)指示現(xiàn)在的數(shù)據(jù)其實(shí)命令)ALE此時(shí)一定為低電平我們可以不關(guān)心他

        2 所以,CLE為 低電平的時(shí)期,其他大部分引腳上都是 灰色的陰影,這代表我們不需要關(guān)心這段時(shí)期這些引腳的電平

        3 那么 這個(gè)數(shù)據(jù)是什么時(shí)候被nand flash讀取到的呢, 注意到 nWE信號(hào) 在上升沿有一個(gè)貫穿所有其他引腳時(shí)序的豎線(這好像是叫生命線?我也不清楚)

               這就是說(shuō)明,寫(xiě)入的數(shù)據(jù)(命令也是數(shù)據(jù)啊,只是可以通過(guò)CLE有效來(lái)區(qū)分)是在 WE的上升沿有效。

               也就是說(shuō),雖然 WE是在低電平有效,但并不是說(shuō) WE一變成低電平,命令就被鎖存了(即真正獲得命令)而是在 WE 的上升沿,命令才真正被鎖存

         

        知道了上面這三點(diǎn),也就知道了一個(gè)大概,那么剩下的圖中也只剩那些 txx 的標(biāo)號(hào)。明顯它指的是時(shí)間,但是具體指什么時(shí)間呢。

        指的就是箭頭兩邊所指的兩條 豎線之間的時(shí)間。(在每個(gè)信號(hào)的跳變沿,都有小豎線)

         

        剩下的就是這些時(shí)間到底是代表什么了。這里沒(méi)什么難的,剛接觸的覺(jué)得看不懂。是因?yàn)橹皬膩?lái)沒(méi)接觸過(guò)。(就像單片機(jī)剛學(xué)的時(shí)候不也是各種不懂,原因就是我們從沒(méi)接觸過(guò))。
這些時(shí)間標(biāo)號(hào),在數(shù)據(jù)手冊(cè)的前面都有 說(shuō)明

        

        比如  tCLS   tCLH 從數(shù)據(jù)手冊(cè)中我們可以看到 分表代表的 CLE建立時(shí)間,和CLE信號(hào)保持時(shí)間。

        簡(jiǎn)單點(diǎn)你可以理解為,我讓 CLE引腳  變成高電平,總得給人間一點(diǎn)時(shí)間去變成高電平吧。總不能瞬間就變成高電平

        不過(guò)從 時(shí)序圖中我們能看到更多的端倪,之前不是說(shuō)過(guò) WE 的上升沿上不是有一個(gè)最長(zhǎng)貫穿其他信號(hào)線的 豎線嗎。我們說(shuō)他指示了,數(shù)據(jù)(命令也是數(shù)據(jù))

        是在上升沿被鎖存的,在 WE 的上升沿,我寫(xiě)到數(shù)據(jù)線上的命令數(shù)據(jù)才真正被鎖存(接收),但是 我們注意到 CLE 信號(hào)在WE上升沿之前有就有效了。

        所以我們說(shuō), 在命令數(shù)據(jù)真正被鎖存之前,CLE 有效的那段 tCLS 時(shí)間叫做 CLE信號(hào)建立時(shí)間。

               WE上升沿后。命令已經(jīng)被接受了,但這時(shí)候 CLE 其實(shí)可以變?yōu)闊o(wú)效了,因?yàn)橐呀?jīng)獲取到命令了

        但是他并沒(méi)有立刻結(jié)束,而是 Tclh時(shí)間之后才結(jié)束。那么我們 稱(chēng)這段 時(shí)間 tCLH CLE 保持時(shí)間。

        
那么再根據(jù)手冊(cè)中的說(shuō)明  tCS 表示 片選信號(hào)建立時(shí)間,tCH表示片選信號(hào)保持時(shí)間

               tDS表示數(shù)據(jù)建立時(shí)間,tDH表示數(shù)據(jù)保持時(shí)間

         

        這里我們看到一個(gè)小規(guī)律,在數(shù)據(jù)手冊(cè)中 以 S 結(jié)尾的時(shí)間通常指的是建立時(shí)間, 以 H 結(jié)尾的時(shí)間指的是保持時(shí)間

              

              

        這里命令鎖存的時(shí)序就分析完了。我們?cè)賮?lái)看看  地址鎖存時(shí)序圖,這個(gè)圖有點(diǎn)復(fù)雜,

        因?yàn)閚and flash的 特性是 地址周期通常需要好幾個(gè),就是一個(gè)地址是分幾次發(fā)送的

        

         

        再給出數(shù)據(jù)手冊(cè)中對(duì)應(yīng)時(shí)間標(biāo)號(hào)的說(shuō)明

        

        
同樣我們按照上面分析的步驟

        1 這里是地址鎖存是時(shí)序,那么我們要注意的其實(shí)就只有 ALE 為高電平期間這段時(shí)序。(寫(xiě)命令啊,ALE有效時(shí)(高電平)指示現(xiàn)在的數(shù)據(jù)其實(shí)是地址)CLE此時(shí)一定為低電平,可以不用管

        
2 所以,ALE 為低電平的時(shí)期,其他大部分引腳上都是 灰色的陰影,這代表我們不需要關(guān)心這段時(shí)期這些引腳的電平

        
3 同樣 WE 的上升沿有一個(gè)貫穿其他信號(hào)線的長(zhǎng)豎線,這也是代表數(shù)據(jù)(這里其實(shí)是地址)在上升沿被鎖存

         

        那么剩下的也好理解

        tCLS 這個(gè)我們不需要關(guān)心,因?yàn)?CLE 壓根就是無(wú)效的。

        tCS 就像之前分析的,它是指 CE片選信號(hào)在 WE上升沿也就是鎖存地址之前的有效時(shí)間,也就是 CE 建立時(shí)間

        tWC 呢? 不知道? 不知道 看手冊(cè)啊,前面也說(shuō)過(guò)這些時(shí)間標(biāo)號(hào)在手冊(cè)中都會(huì)給出。

               從上面手冊(cè)的解釋我們看到,它指的是一個(gè)寫(xiě)周期的時(shí)間

        tWP 寫(xiě)脈沖寬度(也就是 WE是低電平有限,twp指低電平持續(xù)時(shí)間,就是有效時(shí)間)

        tWH 好理解了,就是高電平時(shí)間

        ALS    這不就是 地址信號(hào)  ALE 建立時(shí)間嘛

        ALH   ALE信號(hào)有效保持時(shí)間啊

        TDS TDH 數(shù)據(jù)建立和保持時(shí)間

        就像上面對(duì) 命令時(shí)序的分析,這里 信號(hào)的 建立 保持時(shí)間都是以 數(shù)據(jù)被 鎖存分界點(diǎn)(WE上升沿)

         

        看到這里相信仔細(xì)看的人,應(yīng)該大致該如何看一個(gè)時(shí)序圖了,但是這里 我們牽涉到的 無(wú)非都是一些 上面 建立/保持時(shí)間。

        復(fù)雜點(diǎn)的呢。

         

        下面就來(lái)看一個(gè)復(fù)雜點(diǎn)的時(shí)序圖,其實(shí)也不復(fù)雜,主要是說(shuō)明如何在不看手冊(cè)就能知道 txx指的是什么時(shí)間

         


        

         

        這個(gè)時(shí)序其實(shí)并不復(fù)雜,只是他不是像上面分析的那樣都是一些 建立時(shí)間和保持時(shí)間。這里牽涉到跟多的時(shí)間標(biāo)號(hào)

        不過(guò)就像前面說(shuō)的. 看手冊(cè)! 手冊(cè)里對(duì)每個(gè)時(shí)間參數(shù)都有說(shuō)明。不過(guò)初學(xué)者通常即使看手冊(cè),對(duì)這些時(shí)間參數(shù)也是不知道是什么意思。

        這里我們看手冊(cè)前,先來(lái)自己分析下。方法會(huì)了,手冊(cè)就成了驗(yàn)證你對(duì)不對(duì)的東西了,而不是你尋找答案的東西。

         

        TRC 這個(gè)參數(shù)有點(diǎn)簡(jiǎn)單?此姆秶 是 一個(gè) RE周期 的時(shí)間,那么就跟前面的 tWC 應(yīng)該是一樣的。那它應(yīng)該代表的就是 RE信號(hào)的一個(gè)周期時(shí)間(讀信號(hào)的一個(gè)周期)

        TREA 呢? 看標(biāo)號(hào)看不出所以然,那么我們就看他的起始和結(jié)束時(shí)間 從時(shí)序圖能看到,這個(gè)指的是從 RE有效(變低) 到數(shù)據(jù)出現(xiàn)之間的時(shí)間。

        那么tREA 可想而知就應(yīng)該是 讀信號(hào)有效到數(shù)據(jù)被讀之間的時(shí)間

        后面的都是這個(gè)同樣的分析方法

        比如最后的那個(gè) tRHZ 是從 RE 無(wú)效(高電平)到數(shù)據(jù)線變成高阻態(tài) 之間的時(shí)間(數(shù)據(jù)線畫(huà)在中間表示的是高阻態(tài))

        看下手冊(cè)中的解釋 也基本就是這個(gè)意思

        

         

        到這里 對(duì)于時(shí)序圖怎么看,相信大家都應(yīng)該能理解了。甚至可能連手冊(cè)都不用看,就知道他是什么意思了。因?yàn)槲覀兡軓?時(shí)間的起始地址來(lái)推測(cè)時(shí)間標(biāo)號(hào)的意思

         

         

        上面這些分析,都是很底層的操作,如果我們使用 s3c2440 這種高級(jí)的處理器 這些時(shí)序操作我們根本不需要去實(shí)現(xiàn),頂多也就往幾個(gè)寄存器中

        設(shè)置一下上面說(shuō)的一些時(shí)間 然后,CPU 中的 nand flash控制器會(huì)自動(dòng)完成上面所的所有操作。但是還需要了解的原因是,如果你碰到一個(gè)沒(méi)有

        nand flash 控制器的處理器 怎么辦,那你只能親自實(shí)現(xiàn)這些 具體的 寫(xiě)命令,寫(xiě)地址。等等 單元操作。

        然后才能將這些單元操作組合成 讀數(shù)據(jù),寫(xiě)數(shù)據(jù)等操作(上面說(shuō)過(guò) 比如讀操作 他并不是一個(gè)簡(jiǎn)單的命令而是一系列操作,你要片選使能,然后發(fā)命令(讀命令),

        然后發(fā)地址(要讀的數(shù)據(jù)的地址),需要的話還需發(fā)一個(gè)命令,然后需要等待操作完成,然后讀書(shū)數(shù)據(jù))

         

        說(shuō)完了 這些具體的單元操作,那么我們?cè)賮?lái)看看一個(gè) 讀操作 具體需要哪些步驟。也就是我們需要真正必須掌握的時(shí)序操作

        對(duì)于我這款 nand flash 讀操作時(shí)序如下

        

        我們要注意的主要是 最下面一行 即 I/Ox 信號(hào)線的狀態(tài),他指示了 讀操作需要哪些,單元步驟。

        1 首先 我們看到 有一個(gè) 0x00 是什么?數(shù)據(jù)?地址?命令? ALE/CLE線啊,這兩根線不是決定了現(xiàn)在的數(shù)據(jù)的類(lèi)型嘛

        順著往上看,我們知道0x00是在 CLE有效期間的數(shù)據(jù)那么它就是一個(gè)命令

        2 然后是 address(5Cycle) 即五個(gè)地址序列(這款nand flash 指定讀數(shù)據(jù)的地址時(shí)要發(fā)送五個(gè)地址序列),往上看,是在ALE有效期間的數(shù)據(jù),那么應(yīng)該就是地址了

               (對(duì)于這五個(gè)地址,前面兩個(gè)是列地址,后面三個(gè)是行地址。在nand flash的物理結(jié)構(gòu)中 行地址對(duì)應(yīng)的某一頁(yè),列地址就對(duì)應(yīng)這一頁(yè)中的某一列)

         

        3 接著又是 0x30,此時(shí) CLE有效,那么就是命令了(也就是說(shuō)這款nand flash的讀操作需要兩個(gè)命令)。

               但是之后數(shù)據(jù)并未立刻出來(lái),我們看到在到 DATA Output即數(shù)據(jù)輸出之前還有一段時(shí)間,為什么有這段時(shí)間?

               往上看 R/nB 這個(gè)數(shù)據(jù)線上說(shuō)明了原因,這段時(shí)間內(nèi)它是低電平 即指示現(xiàn)在 處于 忙碌狀態(tài),還未準(zhǔn)備好數(shù)據(jù)輸出。為什么會(huì)這樣?

               因?yàn)槟?寫(xiě)了 一個(gè)命令,寫(xiě)了要讀數(shù)據(jù)的地址,又寫(xiě)了一個(gè)命令。 你總要給 cpu一些時(shí)間去處理這些命令吧,

               R/nB為低電平這段時(shí)間就是 在處理這些命令(實(shí)際上是根據(jù)命令將你定位的那一頁(yè)數(shù)據(jù)讀到內(nèi)部寄存器中),

         R/nB變成高電平了,就指示命令處理完畢,現(xiàn)在數(shù)據(jù)也就可以讀出來(lái)了

         

        綜上我們從手冊(cè)中我們就知道了讀操作的具體步驟,

        1 首先nand flash 也是一個(gè)外設(shè),要訪問(wèn)他就需要片選它,所以在執(zhí)行時(shí)序圖上的步驟之前需要片選nand flash.

        2 看后面就是安裝時(shí)序圖來(lái)了,看時(shí)序圖! 第一步先是發(fā)送一個(gè)命令 0x00.

        3 看時(shí)序圖! 然后發(fā)送五個(gè)地址序列(先發(fā)送兩個(gè)列地址,在發(fā)送三個(gè)行地址(即頁(yè)地址))

        4 看時(shí)序圖! 接著再是一個(gè)命令 0x30.

        5 看時(shí)序圖!  R/nB 引腳為低表示現(xiàn)在正忙,正在處理這些命令,那就要等待 R/nB 引腳變?yōu)楦唠娖?/font>

        6 看時(shí)序圖! 這個(gè)時(shí)候就可以讀數(shù)據(jù)了

        7 一次讀操作結(jié)束了 nand flash 暫時(shí)是不需要使用了,那么別忘了應(yīng)該 取消片選信號(hào)。

         

        至于這每一個(gè)步驟中具體的時(shí)序,cpu中的nand flash控制器會(huì)幫我們完成。我們要做就是設(shè)置幾個(gè)時(shí)間參數(shù)

         

        這里我們反復(fù)強(qiáng)調(diào)了要看時(shí)序圖。其實(shí)學(xué)嵌入式前期對(duì)數(shù)據(jù)手冊(cè)一定要多看,看多了你就回知道,什么東西的你重點(diǎn)要看的,什么是和你的編程操作無(wú)關(guān)的你不需要關(guān)心。這樣后面你才能,拿到一個(gè)外設(shè) 就能寫(xiě)出他的操作。而不用跟著書(shū)背步驟。只要手冊(cè)在就行了。

         

        上面的步驟,是一個(gè)具體的讀操作的步驟,不過(guò)在使用一個(gè)器件之前我們需要初始化一下它。至于初始化也就是設(shè)置我們上面多次提到的

        我們說(shuō)過(guò) s3c2440已經(jīng)幫我做了很多底層的單元操作,我們只需設(shè)置幾個(gè)時(shí)間參數(shù) 片內(nèi)的 nand flash就會(huì)自動(dòng)發(fā)出相應(yīng)操作的時(shí)序操作

        那么到底設(shè)置那幾個(gè)時(shí)間呢。

        s3c2440 手冊(cè)上給出了 需要我們?cè)O(shè)置的幾個(gè)參數(shù)。

        


        

         

        從中我們可以看出 第一幅時(shí)序圖是 命令和地址鎖存的時(shí)序,第二幅是 數(shù)據(jù)讀取和寫(xiě)入的時(shí)序。
可以看出,他們要設(shè)置的時(shí)間都是一樣的。前面分析了那么多,這里應(yīng)該不難 看出

        
1 TACLS 很明表示的是 CLE/ALE 的建立時(shí)間(這里并不準(zhǔn)確,其實(shí)是 CLE/ALE有效到 WE 變成低電平之間的時(shí)間,但 WE 卻是在上升沿才鎖存命令/地址)

        2 TWRPH0 代表的是 WE 的脈沖寬度,即有效時(shí)間

        3 TWRPH1 代表的是 CLE/ALE 的保持時(shí)間

        
那到底設(shè)置成什么數(shù)字呢。既然 上圖中讀/寫(xiě)/命令/地址 操作需要的時(shí)間參數(shù)都是一樣的

        那么我們從 nand flash中隨便找一個(gè) 命令時(shí)序來(lái)對(duì)照不就行了

        就拿上面我們說(shuō)過(guò)的 命令鎖存時(shí)序來(lái)對(duì)比

        

        
那么我們就能得到下面的關(guān)系

        TWRPH0 = tWP

        TWRPH1 = tCLH

        TACLS  = tCLS - tWP

         
然后設(shè)置成多少呢? 看手冊(cè)啊,手冊(cè)中對(duì) tWP  tCLH  tCLS 都會(huì)至少給出 需要的最小時(shí)間

        
這款芯片nand flash手冊(cè)中這三個(gè)參數(shù)要求是

         

        所以 TWRPH0 = tWP  >=12ns

                TWRPH1 = tCLH >=5ns

                TACLS  = tCLS - tWP >=0;

        而這三個(gè)參數(shù)在s3c2440的數(shù)據(jù)手冊(cè)中說(shuō)明為

         

        當(dāng)然這里的時(shí)間都是以 HCLK 為單位的,這幾個(gè)參數(shù) 是在 nand flash控制寄存器中的 NFCONF中設(shè)置的

        這里我沒(méi)用使用MPLL 所以HCLK是 12MHZ

         

        所以 TWRPH0 = 0 TWRPH1 =0 TACLS =0; (如果你的時(shí)鐘頻率比較高,那就要設(shè)別的數(shù)了。當(dāng)然有是有你真不知道,設(shè)置大點(diǎn)總沒(méi)錯(cuò),只不過(guò)速度可能會(huì)慢點(diǎn)。)

               所以 NFCONF =0;(NOFCONF其他位數(shù)據(jù)手冊(cè)中有說(shuō)明,這里只是簡(jiǎn)單讀操作,其他位可以不設(shè)置)

         

        然后是初始化一下 ECC 使能nand flash控制器(我們只是設(shè)置了幾個(gè)時(shí)間參數(shù),時(shí)序的具體操作就是靠他來(lái)完成的,所以要使能他)

        然后先 取消片選nand flash 因?yàn)槲覀儸F(xiàn)在還沒(méi)有操作它啊,只是初始化一下。所以還是應(yīng)該先取消片選,等真正讀的時(shí)候再使能片選信號(hào)

         

        NFCONT = (1<<4) | (1<<1) (1<<0);

        (數(shù)據(jù)手冊(cè)中有對(duì)應(yīng)位的說(shuō)明)

        最后,第一次使用nand flash 我們需要復(fù)位操作一下。

        綜上,nand flash 的初始化代碼如下

        void nand_init(void){

                NFCONF =0;

                NFCONT = (1<<4) | (1<<1) | (1<<0);

                nand_reset();  //nand reset代碼在后面

        }

         

        下面代碼一些地址的寫(xiě)法是與 nand flash 型號(hào)有關(guān)的。具體需要參考芯片手冊(cè)

              

         

        void select_chip(void){

                NFCONT  &= (~(1<<1)) ;   

                int i;

                for(i=10;i>0;i--);

        }

        void deselect_chip(void){

                NFCONT |= (1<<1);

                int i;

                for(i=10;i>0;i--);

        }

         

        void write_command(unsigned char command){

                NFCMMD = command;

                int i;

                for(i=10;i>0;i--);

        }

         

        /*

               這款nand flash 的頁(yè)大小是 2K

               五個(gè)地址周期  (2個(gè)列地址 和3和行地址(頁(yè)地址))

        */

        void write_address(unsigned int address){

                unsigned int page = address/2048;

                unsigned int col  = address&2048;

         

                int i;

                NFADDR = col & 0xff;

                for(i=5;i>0;i--);

                NFADDR = (col >>8) & 0x0f;

                for(i=5;i>0;i--);

                NFADDR = page & 0xff;

                for(i=5;i>0;i--);

                NFADDR = (page >>8)& 0xff;

                for(i=5;i>0;i--);

                NFADDR = (page >>16)&0x01;

                for(i=5;i>0;i--);

        }

         

        unsigned char read_one_data(void){

                return NFDATA;

                int i;

                for(i=10;i>0;i--);

        }

         

        void wait_ready(void){

                while(!(NFSTAT & 1));

                int i;

                for(i=10;i>0;i--);

        }

         

         

        static void nand_reset(void){

                select_chip();

                write_command(0xff);

                wait_ready();

                deselect_chip();

        }

        void nand_init(void){

                NFCONF =0;

                NFCONT = (1<<4) | (1<<1) | (1<<0);

         

                nand_reset();

        }

         

        /*

        nand flash 的讀操作是以頁(yè)為單位的。

         des: nand flash中讀出的數(shù)據(jù)放到哪

         start_addr: 從哪里開(kāi)始讀

         size: 讀多大

        */

        void nand_read(unsigned char *des,unsigned int start_addr,unsigned int size){

                unsigned int col  = start_addr & 2048;

         

                select_chip();

                unsigned int start = start_addr;

                unsigned int end   = start_addr + size;

                while(start < end){                             //每讀一頁(yè)需要發(fā)一次命令

                        write_command(0x00);

                        write_address(start);

                        write_command(0x30);

                        wait_ready();

         

                        while((col<2048) && (start<end)){ 在一頁(yè)中讀,我用的型號(hào)一頁(yè)大小為2k[="" font][="" color][="" p][p="26," null,="" left]="" *des="read_one_data();

[p=26," des++;[="" col++;[="" start++;[="" }[="" col="0;
[p=26," deselect_chip();[="" p]

評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
zhangli019 + 5 贊一個(gè)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂3 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:23978 發(fā)表于 2014-9-15 10:34 | 只看該作者
太好了,受教了!
回復(fù)

使用道具 舉報(bào)

板凳
ID:70371 發(fā)表于 2014-12-18 22:39 來(lái)自手機(jī) | 只看該作者
學(xué)習(xí) 學(xué)習(xí) 學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

地板
ID:70104 發(fā)表于 2014-12-19 14:15 | 只看該作者
有你,才有我們這些學(xué)員啊
回復(fù)

使用道具 舉報(bào)

5#
ID:70104 發(fā)表于 2014-12-19 14:15 | 只看該作者
謝謝了。。學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

6#
ID:29438 發(fā)表于 2015-2-6 13:14 | 只看該作者
多謝!
回復(fù)

使用道具 舉報(bào)

7#
ID:75332 發(fā)表于 2015-4-12 13:06 | 只看該作者
學(xué)習(xí) 學(xué)習(xí) 學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

8#
ID:75332 發(fā)表于 2015-4-12 14:55 | 只看該作者
太好了,受教了!
回復(fù)

使用道具 舉報(bào)

9#
ID:72611 發(fā)表于 2015-4-13 09:36 | 只看該作者
很詳細(xì)學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

10#
ID:90900 發(fā)表于 2016-1-17 17:00 | 只看該作者
太好了,這個(gè)問(wèn)題已經(jīng)困擾我好長(zhǎng)時(shí)間了,真心感謝
回復(fù)

使用道具 舉報(bào)

11#
ID:63815 發(fā)表于 2016-2-22 15:56 | 只看該作者
好東西,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

12#
ID:152324 發(fā)表于 2016-12-5 16:40 | 只看該作者
通俗易懂
回復(fù)

使用道具 舉報(bào)

13#
ID:611584 發(fā)表于 2019-9-21 11:36 來(lái)自手機(jī) | 只看該作者
講的太好了,受教受益了,謝謝。
回復(fù)

使用道具 舉報(bào)

14#
ID:611584 發(fā)表于 2019-9-21 11:37 來(lái)自手機(jī) | 只看該作者
真心好,受益不淺。
回復(fù)

使用道具 舉報(bào)

15#
ID:491589 發(fā)表于 2020-1-6 10:43 | 只看該作者
感謝樓主非常詳細(xì)的分析,比其他書(shū)上清晰多了!受教!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表