OK6410裸機簡單的NANDFLASH讀寫及擦

OK6410裸機簡單的NANDFLASH讀寫及擦

文章轉載請註明出處:http://blog.csdn.net/wf395962475/article/details/8221250

今天完成了OK6410裸機簡單的NANDFLASH讀寫及擦除,那麼直接進入正題。

我的操作環境是:

主機:WIN7系統, VMware RHEL5  8.0 虛擬機。

開發板:OK6410,A板,256M+2G 。

LCD :飛凌4.3 寸TFT ,WXCAT43, 480*272

Uboot:飛凌體統的Uboot。

移植內核版本:Linux-3.0.1。

參考內核: 飛凌提供的Linux-3.0.1

如果你是參考這篇博文來移植的話,我還是要強調一下上面的開發板環境移植內核的版本,這很重要,因爲不同的硬件有不同的要求和

說明,而不同的內核版本之間又有着不同的差異性。當然這些也並不是絕對的。其他的環境也可以參考這篇博文。

個人認爲要學會使用NAND FLASH的讀寫等操作,則必須對NAND FLASH的結構以及存儲方式、訪問時序等做進一步的瞭解!下面開始學習。

1、NAND FLASH的基本結構

本人採用飛凌OK6410-A+256M+2G開發板上的NAND FLASH芯片,型號是K9GAG08U0D。可以去谷歌搜索它的datasheet。

下面先介紹NAND FLASH引腳以及內部存儲器組織結構。

NAND FLASH(K9GAG08U0D)引腳圖如下,圖1.1

上圖簡單翻譯如下:
1. I/O0 ~ I/O7:用於輸入地址/數據/命令,輸出數據
2. CLE:Command Latch Enable,命令鎖存使能,在輸入命令之前,要先在模式寄存器中,設置CLE使能
3. ALE:Address Latch Enable,地址鎖存使能,在輸入地址之前,要先在模式寄存器中,設置ALE使能
4. CE#:Chip Enable,芯片使能,在操作Nand Flash之前,要先選中此芯片,才能操作
5. RE#:Read Enable,讀使能,在讀取數據之前,要先使CE#有效。
6. WE#:Write Enable,寫使能,在寫取數據之前,要先使WE#有效。
7. WP#:Write Protect,寫保護
8. R/B#:Ready/Busy Output,就緒/忙,主要用於在發送完編程/擦除命令後,檢測這些操作是否完成,忙,表示編程/擦除操作仍在進行中,就緒表示操作完成.
9. Vcc:Power,電源
10. Vss:Ground,接地
11. N.C:Non-Connection,未定義,未連接。
[小常識]
    在數據手冊中,你常會看到,對於一個引腳定義,有些字母上面帶一橫槓的,那是說明此引腳/信號是低電平有效,比如你上面看到的RE頭上有個橫線,就是說明,此RE是低電平有效,此外,爲了書寫方便,在字母后面加“#”,也是表示低電平有效,比如我上面寫的CE#;如果字母頭上啥都沒有,就是默認的高電平有效,比如上面的CLE,就是高電平有效。還有的是在字母前面加個小n,例如nRE,這也是表示低電平有效的。

1.1 NAND FLASH(K9GAG08U0D)內部存儲器組織結構圖如下

 圖1.2

NAND FLASH(K9GAG08U0D)主的存儲器主要有2部分組成:頁(Page)、塊(Block)。

●    每頁大小爲:(4K+218)字節,4K用來存儲數據,218字節主要用於存儲控制信息。如圖1.2,每頁末尾都有218字節的額外空間,主要是爲了便於管理每一頁。Eg,使用這218位中的某一位表示該頁是否已經寫滿數據的標誌位。如果該位爲1,則表示該頁寫滿。反之,表示該頁爲空。只需要查詢該位即可知道該頁是否存滿數據。

●   每塊大小爲:128個頁

整個NAND FLASH(K9GAG08U0D)由4K(4096)個塊組成。

NAND FLASH容量=塊的數目*每塊的容量

                                =塊的數目*(每塊包含頁的數目*每頁的容量)

                  =4KBlocks*(128Pages*(4k+218b))

                  =4KBlocks*128Pages*4k+4KBlocks*128Pages*218b

                  =2048MBytes+109Mbytes

經過計算知,前面的2048M表示該NAND FLASH可以存儲2G個字節數據,後面109M字節的數據主要用於保存每一頁的控制信息

 

(a,k,a) NAND FLASH類似與整個小區,每塊(Block)類似於小區裏面的一棟樓,每個頁(Page)類似於每一層樓。

1.2 Nand Flash中的特殊硬件結構

由於nand flash相對其他常見設備來說,比較特殊,所以,特殊的設備,也有特殊的設計,所以,有些特殊的硬件特性,就有必要解釋一下:
頁寄存器(Page Register):由於Nand Flash讀取和編程操作來說,一般最小單位是頁,所以,nand flash在硬件設計時候,就考慮到這一特性,對於每一片,都有一個對應的區域,專門用於存放,將要寫入到物理存儲單元中去的或者剛從存儲單元中讀取出來的,一頁的數據,這個數據緩存區,本質上就是一個buffer,但是隻是名字叫法不同,datasheet裏面叫做Page Register,此處翻譯爲頁寄存器,實際理解爲頁緩存,更爲恰當些。而正是因爲有些人不瞭解此內部結構,才容易產生之前遇到的誤解:以爲內存裏面的數據,通過Nand Flash的FIFO,寫入到Nand Flash裏面去,就以爲立刻實現了實際數據寫入到物理存儲單元中了。而實際上,只是寫到了這個頁緩存中,只有等你發了對應的編程第二階段的確認命令0x10之後,實際的編程動作纔開始,纔開始把頁緩存中的數據,一點點寫到物理存儲單元中去。這也是爲什麼發完命令0x10之後需要等待一段時間的原因。
所以,簡單總結一下就是,對於數據的流向,實際是經過了如圖1.3下步驟:

2. NAND FLASH接口電路

因爲S3C6410處理器內部已經集成了NAND FLASH控制器。接口電路比較簡單,只需將S3C6410的引腳和NAND FLASH對應的引腳接上即可。如圖2.1

圖2.1

S3C6410處理器與NAND Flash硬件連線(如圖2.2)

I/O0- I/O78位命令、地址、數據複用總線。

CLE:命令鎖存使能。

ALE:地址鎖存使能。

/WE:寫使能。在寫命令輸入後,數據在/WE脈衝的控制下依次從數據寄存器寫入存儲單元。

/WP:硬件寫保護。在系統上電或斷電時保持低電平。

/RE:讀使能。在讀命令輸入後,數據在/RE脈衝的控制下依次從存儲單元讀出到數據寄存器。

CE:芯片使能,高電平有效。

R/B:芯片Ready/Busy狀態檢測。

如圖2.2

【爲何需要ALE和CLE】突然想明白了,Nand Flash中,爲何設計這麼多的命令,把整個系統搞這麼複雜的原因了:
比如命令鎖存使能(Command Latch Enable, CLE)和地址鎖存使能(Address Latch Enable,ALE),那是因爲,Nand Flash就8個I/O,而且是複用的,也就是,可以傳數據,也可以傳地址,也可以傳命令,爲了區分你當前傳入的到底是啥,所以,先要用發一個CLE(或ALE)命令,告訴nand Flash的控制器一聲,我下面要傳的是命令(或地址),這樣,裏面才能根據傳入的內容,進行對應的動作。否則,nand flash內部,怎麼知道你傳入的是數據,還是地址,還是命令啊,也就無法實現正確的操作了.

3 S3C6410 NAND Flash控制器原理

S3C6410 NAND Flash控制器支持的主要特徵有:

a. 支持512字節頁和2K字節頁。

b. 軟件模式:可以直接訪問NAND Flash存儲器。

c. 接口:支持8NAND Flash接口。

d. 硬件ECC產生、檢錯和表示,軟件糾錯。

e. 支持SLCMLCNAND Flash存儲器:1位、4位和8位的ECC(推薦對SLC NAND Flash使用1ECC,對MLC NAND Flash使用4位和8ECC)。

f. 支持對數據寄存器和ECC數據寄存器的字節、半字和字訪問,對其它寄存器進行按字訪問。

g. Steppingstone支持字節、半字和字訪問。

 

3.1 NAND FLASH控制器的工作機制。

NAND FLASH控制器的工作機制如下圖3.1所示。在上電覆位時,NAND FLASH控制器將通過XOM引腳狀態來獲得關於連接NAND FLASH的信息。在上電或系統復位後,NAND FLASH控制器自動加載4K的啓動代碼。加載完成後,啓動代碼將在Stepping Stone中被執行。如圖3.1

如圖3.1

NOTE:在自動導入期間,ECC是未被選中狀態。因此,前4K的NAND FLASH絕不能有錯位。

3.2 NAND FLASH MEMORY TIMING

如圖3.2

3.3 NAND FLASH ACCESS

6410 does not support NAND flash access mechanism directly. It only supports signal control mechanism for NAND flash access. Therefore software is responsible for accessing NAND flash memory correctly.

 

S3C6410 僅支持軟件模式訪問。

1. Writing to the command register (NFCMMD) = the NAND Flash Memory command cycle

2. Writing to the address register (NFADDR) = the NAND Flash Memory address cycle

3. Writing to the data register (NFDATA) = write data to the NAND Flash Memory (write cycle)

4. Reading from the data register (NFDATA) = read data from the NAND Flash Memory (read cycle)

5. Reading main ECC registers and Spare ECC registers (NFMECCD0/1, NFSECCD) = read data from the

In NAND flash access, you must check the RnB status input pin by polling the signal or using interrupt.

(1)寫命令寄存器=NAND FLASH 存儲器命令週期。

(2)寫地址寄存器=NAND FLASH 存儲器地址週期。

(3)寫數據寄存器=寫數據到NAND FLASH 存儲器(寫週期)。

(4)讀數據寄存器=從NAND FLASH 存儲器讀數據(讀週期)。

(5)讀主ECC 寄存器和備用ECC 寄存器=從NAND FLASH 存儲器讀數據。

在軟件模式下,必須通過利用檢測和中斷來檢查RnB 輸入引腳的狀態。

3.4 數據寄存器的配置

圖3.3所示 A 字訪問 B半字訪問 C字節訪問

 

圖3.3

3.5 NAND FLASH MEMORY CONFIGURATION

NAND FLSAH 存儲器結構圖(圖3.4)

3.4

NOTE:NAND 控制器可以支持2個NAND FLASH 存儲器,如果想要從NAND啓動,則必須使用Xm0CSn[2]進行導入。

3.5 NAND FLASH 控制寄存器列表

本次只配置以下和本次幾個相關的寄存器(如圖),ECC基本都不用管。以後需要再說。配置寄存器會在初始化時一起設置。

如圖3.5

4 NAND FLASH 讀寫的相關配置

通過以上對NAND FLASH 相關介紹,對NAND FLASH有一定了解,但具體的操作步驟還是很模糊,以下提供一個簡單操作步驟,不一定適合所有的,但基本原理都是這樣。實際情況根據自己的芯片具體設置,在此只供參考學習!

訪問NAND FLASH操作步驟:

1.    片選:選中NAND FLASH

2.    發命令:命令數據、命令鎖存、寫使能

3.    發地址:地址數據、地址鎖存、寫使能

4.    發數據:寫數據、寫使能

5.    讀寫

6.    取消片選

相關解釋:(理解的可以不用看了 嘿嘿..)

2.發命令,即對NAND FLASH 採取哪種操作,讀、寫還是擦除?

3.發地址,即對NAND FLSAH的哪一頁進行上述操作?

4.發數據,在此期間也要檢測NAND FLASH 的內部狀態。

在本次的實驗中只用到以下常用的幾個需要發送的命令 Read 、Page Program、Block Erase、Reset如圖4.1所示。用到後會做解釋。

如圖4.1

4.1 NAND Flash的初始化

在以後的講解中會用的實驗中的函數,使用時請注意修改!

按照NAND Flash讀寫操作步驟:

1.    片選:Xm0CSn2引腳設爲nand flash cs0片選 nand使用memory subsystem port 0  如圖4.2寄存器配置

如圖4.2

MEM_SYS_CFG &=~(1<<1);//選中Xm0CSn2

2.    配置NFCONF

如圖4.3所示需要設置以下幾個參數:

圖4.3

對NFCONF初始化主要是確定TACLS、TWRPH0、TWRPH1三個位的值。在設置之前,先講一下TACLS、TWRPH0、TWRPH1代表什麼意思和他們的關係。

如圖4.4所示

 

如圖4.4

●    TACLS表徵了從CLE/ALE鎖存信號有效到寫信號使能經過的時間,具體時間=HCLK時鐘週期*TACLS。

●    TWRPH0表徵了寫有效持續時間,具體時間=HCLK時鐘週期*(TWRPH0+1)。

●    TWRPH1表徵了寫無效到鎖存無效之間的時間,具體時間=HCLK時鐘週期*(TWRPH1+1)。

三個值的初始化需要與數據手冊的時序關係聯繫起來看。如圖4.5

如圖4.5

 

對比如圖4.4和如圖4.5兩圖可以得到如下關係:

●    TACLS表徵的鎖存到寫有效時間與K9GAG08U0D手冊中的tCLS-Twp對應

●    TWRPH0表徵的寫有效的持續時間與K9GAG08U0D手冊中的tWP對應。

●    TWRPH1表徵的寫無效到鎖存無效之間的時間與K9GAG08U0D手冊中的TCLH對應。

因此只有確定tCLS、Twp、TCLH三個參數,就可以確定TACLS、 TWRPH0 、TWRPH1。

結合K9GAG08U0D手冊中的時序參數進行計算。如圖4.6所示

如圖4.6

在系統初始化階段,HCLK=133MHz

有上面公式計算知,TWRPH0最小值爲1,TACLS和TWRPH1都爲0均可。但根據飛凌官方給的資料,時間應當延長一些,這樣會更穩定,剛纔那是算出的最小值!因此可以如下設置:

  1. #define TACLS    7//0 //  
  2.   
  3. #define TWRPH0   7//大於1  小於7  
  4.   
  5. #define TWRPH1   7//0 //大於0 小於7  
  6.   
  7.  NFCONF &=~((0x7<<4)|(0x7<<8)|(0x7<<12)|(1<<30));  
  8.   
  9.  NFCONF |=((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));  

3.    配置NFCONT

寄存器NFCONT,用於開啓NAND FLASH控制器

如圖4.7所示需要配置。

如圖4.7

//使能 nand flash controller

NFCONT |=1;

  NFCONT&=~(1<<16);//選中Soft Disable lock

4.    復位

  1. void reset()  
  2.   
  3. {  
  4.   
  5.   nand_select();//選中  
  6.   
  7.   nand_cmd(0xFF);//發出0xff命令  
  8.   
  9.   nand_ready();//等待就緒  
  10.   
  11.   nand_deselect();//取消選中  
  12.   
  13. }  
  14.   
  15. void nand_select()  
  16.   
  17. {  
  18.   
  19.    NFCONT &=~(1<<1);  
  20.   
  21. }  
  22.   
  23.    
  24.   
  25. void nand_deselect()  
  26.   
  27. {  
  28.   
  29.   NFCONT |=1<<1;  
  30.   
  31. }  
  32.   
  33. void nand_cmd(unsigned char cmd)  
  34.   
  35. {  
  36.   
  37.   NFCMMD = cmd;  
  38.   
  39. }  
  40.   
  41. void nand_ready()  
  42.   
  43. {  
  44.   
  45.   while(!(NFSTAT&1));//讀取狀態值,檢測NAND FLASH是否處於忙狀態。  
  46.   
  47. }  


5.    NAND FLASH 頁寫入函數

NAND FLASH主要用於大路數據段的存取,因此向NAND FLASH寫入數據是以頁爲單位的。NAND FLASH頁寫入函數的功能是向某一頁寫入數據。NAND FLASH由不同的塊組成,每塊包含128頁,因此,要想寫入某一頁,首先需要確定該頁屬於哪一個塊。類似前面將的小區的例子,向某一頁寫數據,就像給某一層樓的所有用戶送快遞,首先要找到哪棟樓,然後在確定是哪層。

NAND FLASH頁寫入命令有2個,分別是0x80和0x10。

頁寫入步驟爲:

A.    發送頁寫命令0x80

B.    發送頁地址

C.    發送要寫入的數據

D.    發送頁寫入確定命令0x10

E.    檢測忙信號

F.    取消選中

NOTE:爲什麼需要發送2次命令?很多人應該也沒有注意到此問題,最開始我也沒有明白什麼意思。參看數據手冊和相關資料才明白。當發送頁寫入確認命令0x10之前,並沒有將數據寫入NAND FLASH的存儲單元,僅僅是將數據寫入了NAND FLASH的數據寄存器(Data Register & S/A)裏,如下圖4.8所示。只有收到頁寫入命令0x10後,NAND FLASH纔會自動將數據寄存器中的數據寫入對應的存儲單元中。這樣做的主要目的是爲了降低頁的寫入時間。

圖4.8

在發送頁寫入命令後,NAND FLASH會自動將數據寄存器中的數據寫入對應的存儲單元中,這需要一定的時間。因此,在發送完頁寫入確定命令0x10之後,需要不斷地檢測忙信號,只有NAND FLASH真正寫完數據後,才能對其進行後續的操作。

  1. int nand_write_page(unsigned int addr,unsigned char *buf)  
  2.   
  3. {  
  4.   
  5.   int i = 0;  
  6.   
  7.   unsigned char RdDat[4096];  
  8.   
  9.   if(addr%4096!=0)// 輸入必須是頁的開始地址  
  10.   
  11.   {  
  12.   
  13.     printf("error:nand write must start with page addr");  
  14.   
  15.     return -1;  
  16.   
  17.   }  
  18.   
  19.   nand_select();//選中  
  20.   
  21.   nand_cmd(0x80);//發頁寫命令  
  22.   
  23.   nand_write_addr(addr);//寫地址  
  24.   
  25.   for(i = 0;i<4096;i++)//判斷是那一頁地址  
  26.   
  27.   {  
  28.   
  29.     write_data(buf[i]);  
  30.   
  31.   }  
  32.   
  33.   nand_cmd(0x10); //發送頁寫入確定命令  
  34.   
  35.   nand_ready();//檢測忙信號  
  36.   
  37.   nand_deselect();//取消片選  
  38.   
  39.   nand_read(addr,RdDat,4096);//讀剛纔寫進去的數據  
  40.   
  41.   for(i = 0 ;i<4096;i++)  
  42.   
  43.   {  
  44.   
  45.     if(RdDat[i]!=buf[i])  
  46.   
  47.     {  
  48.   
  49.       printf("%d   0x%x:0x%x\n",i,RdDat[i],buf[i]);  
  50.   
  51.       printf("check error:addr:0x%x,offsize:0x%x\n",addr,i);  
  52.   
  53.       return -1;  
  54.   
  55.     }  
  56.   
  57.   }  
  58.   
  59.   return 0;  
  60.   
  61. }  
  62.   
  63. void nand_write_addr(unsigned int addr)  
  64.   
  65. {  
  66.   
  67.   unsigned int colum = 0;  
  68.   
  69.   unsigned int page = 0;  
  70.   
  71.    
  72.   
  73.   colum = addr%4096;//地址所處哪列  
  74.   
  75.   page  = addr/4096;//地址所處哪頁  
  76.   
  77. //這兩個地址表示從頁內哪裏開始  
  78.   
  79.   NFADDR = colum&0xFF;  
  80.   
  81.   NFADDR = (colum>>8&0xFF);  
  82.   
  83. //  下面三個地址表示哪一頁  
  84.   
  85.   NFADDR = page&0xFF;  
  86.   
  87.   NFADDR = (page>>8&0xFF);  
  88.   
  89.   NFADDR = (page>>16&0xFF);  
  90.   
  91. }  

6.    NAND FLASH 頁讀取函數

相對NAND FLASH 頁寫入函數,NAND FLASH 頁讀取函數變得較簡單,頁讀取命令也需要2個命令:頁讀取發起命令0x00和頁讀取確認命令0x30。

基本原理:當發送頁讀取0x00命令後,需要緊接着發送需要讀的頁的絕對地址,然後發送頁讀取確認命令0x30,NAND FLASH收到第2個命令0x30後,自動將數據從內部存儲單元複製到了NAND FLASH的數據寄存器(Data Register & S/A)裏,在此期間需要檢測忙信號(如果忙信號有效,說明NAND FLASH存儲單元中的數據還沒有全部複製到數據寄存器),數據複製完畢後,可以通過讀取S3C6410內部的的特殊功能寄存器NFDATA來得到所需要的數據。

NAND FLASH頁讀取命令有2個,分別是0x00和0x30。

頁讀取操作步驟:

A.    發送頁讀取發起命令0x00

B.    發送地址

C.    發送頁讀取確認命令0x30

D.    檢測忙信號

E.    從S3C6410處理器寄存器NFDATA中讀取數據

F.    取消選中

 

  1. void nand_read(unsigned int start_addr,unsigned char *buf,int len)  
  2.   
  3. {  
  4.   
  5.    int i = 0;  
  6.   
  7.    int readsum = 0;  
  8.   
  9.      
  10.   
  11.    i = start_addr%4096;  
  12.   
  13.    nand_select();//片選  
  14.   
  15.    while(readsum<len)  
  16.   
  17.    {  
  18.   
  19.      //讀一次  
  20.   
  21.      nand_cmd(0x00);//發送頁讀取發起命令0x00  
  22.   
  23.      nand_write_addr(start_addr);//寫開始地址  
  24.   
  25.      nand_cmd(0x30);//發送頁讀取確認命令0x30  
  26.   
  27.      nand_ready();//等待檢測忙信號,即是否讀取完全  
  28.   
  29.      for(;i < 4096&&readsum<len;i++)  
  30.   
  31.      {  
  32.   
  33.        *buf = read_data();  
  34.   
  35.        buf++;  
  36.   
  37.        start_addr++;  
  38.   
  39.        readsum++;  
  40.   
  41.      }  
  42.   
  43.      i = 0;  
  44.   
  45.    }  
  46.   
  47.    nand_deselect();//取消片選  
  48.   
  49. }  


 

7. NAND FLASH塊擦除函數

前面講過NAND FLASH的讀、寫函數,但對NAND FLASH寫之前,需要先進行擦除,這是由NAND FLASH自身的存儲器結構決定的。對某一個存儲單元來說,只能向該單元寫0,無法向其寫1。所謂擦除是將所有的存儲單元全部寫1,然後再對其進行寫操作,0可以寫入,1雖然無法寫入,但由於擦除時該單元已經爲1,所以該存儲單元保留1.因此,利用擦除操作達到間接地向存儲單元寫1的目的。

擦除操作是以塊爲單位進行的,無法對一頁進行擦除操作。

小提示:結合前面的例子,NAND FLASH擦除操作就像在小區裏面打掃衛生,NAND FLASH的一個塊就像小區裏面的一棟樓,擦除只能以塊爲單位進行,就像打掃衛生時,只能整棟樓都打掃。

塊擦除基本原理:發出塊擦除發起命令0x60後,需要發送三個地址週期的塊地址(注意,因爲塊地址只使用A13-A31,所以需要三個地址週期),最後發送塊擦除確認命令0xd0,NAND FLASH接收到塊擦除命令後會啓動內部的擦除過程。可以通過檢測忙信號來確認擦除是否成功。

 前面講到,每個頁面大小事4K+218Bytes,因此,頁內地址使用A0-A12來尋找;每塊包含128頁,因此,使用地址A13-A19來尋址,整個NAND FLASH包含4K個塊,(但有2片Plane0和Plane1,使用A20來尋址,)所以單個使用A21-A31(也就是2K)來尋址。

塊擦除操作需要2個命令:塊擦除發起命令0x60和塊擦除確認命令0xd0.

塊擦除操作步驟:

A.塊擦除發起命令0x60

B.發送塊地址

C.塊擦除確認命令0xd0

D.檢測忙信號

E.取消選中

  1. int nand_erase_block(unsigned int addr)  
  2.   
  3. {  
  4.   
  5.   unsigned int page = 0;  
  6.   
  7.    
  8.   
  9.   page  = addr/4096;//查找所在塊  
  10.   
  11.   if(addr%4096*128!=0)//必須按塊擦除  
  12.   
  13.   {  
  14.   
  15.     printf("error:nand erase must start with block addr");  
  16.   
  17.     return -1;  
  18.   
  19.   }  
  20.   
  21.   nand_select();//選中  
  22.   
  23.   nand_cmd(0x60);//發塊擦除發起命令  
  24.   
  25. //發送三個地址週期的塊地址  
  26.   
  27.   NFADDR = page&0xFF;  
  28.   
  29.   NFADDR = (page>>8&0xFF);  
  30.   
  31.   NFADDR = (page>>16&0xFF);  
  32.   
  33.   nand_cmd(0xd0);//發送塊擦除確認命令  
  34.   
  35.   nand_ready();//檢測忙信號,即是否擦除完成  
  36.   
  37.   nand_deselect();//取消選中  
  38.   
  39. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章