Nand Flash介紹和Nand Flash控制器使用
一、Flash介紹
常用的flash型別有NOR Flash 和Nand Flash 兩種;
(1)Nor Flash
1、Nor Flash的介面和RAM完全相同,可以隨機訪問任意地址的資料,在其上進行讀操作的效率非常高,但是擦除和寫操作的效率很低,另外,Nor Flash的容量一般比較小,通常,Nor Flash用於儲存程式;
2、Nor Flash的塊大小範圍為64KB—128KB;
3、擦寫一個Nor Flash塊需要4s,
4、市場上Nor Flash 的容量通常為1MB—4MB
(2)Nand Flash
1、Nand Flash的介面僅僅包含幾個I/O引腳,需要序列地訪問,Nand Flash進行擦除和寫操作的效率很高,容量較大,
通常Nand Flash用於儲存資料;
2、Nand Flash的塊大小範圍為8KB—64KB;
3、擦寫一個Nand Flash塊需要2ms;
4、Nand Flash 一般以512位元組為單位進行讀寫
5、 市場上 Nand Flash 的容量一般為 8M—512M
二、Nand Flash的物理結構
以三星公司生產的 K9F1208U0M 為例:
1、容量:64MB,
一共4個層;
每層1024個塊(block);
1塊包含32頁
1頁包含 512 + 16 = 528個位元組
2、外部介面:8個I/O口,5個使能訊號(ALE、CLE、nWE、nRE、nCE),1個狀態引腳(RDY/B),1個防寫引腳(nWE);
3、命令、地址、資料都通過8個I/O口輸入輸出;
4、寫入命令、地址、資料時,都需要將nWE、nCE訊號同時拉低;資料在WE上升沿被鎖存;
5、CLE、ALE用來區分I/O引腳上傳輸的是資料還是地址;
6、64MB的空間需要26位地址,因此以位元組為單位訪問Flash時需要4個地址序列;
7、讀/寫頁在發出命令後,需要4個地址序列
三、Nand Flash訪問方法
1 特殊功能暫存器定義 #define rNFCONF (*(volatile unsigned int *)0x4e000000) #define rNFCMD (*(volatile unsigned char *)0x4e000004) #define rNFADDR (*(volatile unsigned char *)0x4e000008) #define rNFDATA (*(volatile unsigned char *)0x4e00000c) #define rNFSTAT (*(volatile unsigned int *)0x4e000010) #define rNFECC (*(volatile unsigned int *)0x4e000014) #define rNFECC0 (*(volatile unsigned char *)0x4e000014) #define rNFECC 1 (*(volatile unsigned char *)0x4e000015) #define rNFECC2 (*(volatile unsigned char *)0x4e000016) 2 操作的函式實現 1. 傳送命令 #define NF_CMD(cmd) {rNFCMD=cmd; } 2. 寫入地址 #define NF_ADDR(addr) {rNFADDR=addr;} 3. Nand Flash 晶片選中 #define NF_nFCE_L() {rNFCONF&=~(1<<11);} 4. Nand Flash 晶片不選中 #define NF_nFCE_H() {rNFCONF|=(1<<11);} 5. 初始化 ECC #define NF_RSTECC() {rNFCONF|=(1<<12);} 6. 讀資料 #define NF_RDDATA() (rNFDATA) 7. 寫資料 #define NF_WRDATA(data) {rNFDATA=data;} 8. 獲取Nand Flash 晶片狀態 #define NF_WAITRB() {while(!(rNFSTAT&(1<<0)));} 0/假: 表示Nand Flash 晶片忙狀態 1/真:表示Nand Flash 已經準備好 3.NandFlash讀寫擦具體實現。操作Nand Flash時,先傳輸命令,然後傳輸地址,最後讀、寫資料,期間要檢查flash的狀態;
K9F1208U0M 一頁大小為528位元組,而列地址A0——A7可以定址的範圍是256位元組,所以將一頁分為A、B、C三個區:
A區:0—255位元組
B區:256—511位元組
C區:512—527位元組
(0)Nand Flash 初始化
void NF_Init(void)
{
/* 設定 Nand Flash 配置暫存器, 每一位的取值見1.3 節 */
rNFCONF=(1<< 15)|(1<<14)|(1<< 13)|(1<<12)|(1<< 11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
/* 復位外部 Nand Flash 晶片 */
NF_Reset();
}
(1)復位
命令:FFh
步驟:發出命令即可復位Nand Flash晶片;
static void NF_Reset(void)
{
int i;
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0xFF); /* 復位命令 */
for(i=0;i< 10;i++); /* 等待tWB = 100ns. */
NF_WAITRB(); /* wait 200~500us; */
NF_nFCE_H(); /* 取消Nand Flash 選中*/
}
(2)讀操作
命令:
00h——讀A區
01h——讀B區
50h——讀C區
操作步驟:
1、發出命令 00h、01h 或50h, 00h將地址位A8設為0, 01h將A8設為1 ;
2、依次發出4個地址序列;
3、檢測R/nB,待其為高電平時,就可以讀取資料了;
引數說明:block :塊號
page :頁號
buffer :指向將要讀取到記憶體中的起始位置
返回值:1:讀成功
0 :讀失敗
static int NF_ReadPage(unsigned int block, unsigned int page, unsigned char *buffer)
{
int i;
unsigned int blockPage;
unsigned char ecc0, ecc1, ecc2;
unsigned char *bufPt=buffer;
unsigned char se[16];
page=page&0x1f;
blockPage=(block<<5)+page;
NF_RSTECC(); /* 初始化 ECC */
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x00); /* 從A 區開始讀 */
NF_ADDR(0); /* A0~A7 位(Column Address) */
NF_ADDR(blockPage&0xff); /* A9A 16, (Page Address) */
NF_ADDR((blockPage>>8)&0xff); /* A17A24, (Page Address) */
NF_ADDR((blockPage>> 16)&0xff); /* A25, (Page Address) */
/* 等待Nand Flash 處於再準備狀態 */
for(i=0;i< 10;i++);
NF_WAITRB(); /*等待 tR(max 12us) */
/* 讀整個頁, 512 位元組 */
for(i=0;i<512;i++)
{
*bufPt++=NF_RDDATA();
}
/* 讀取 ECC 碼 */
ecc0=rNFECC0;
ecc 1=rNFECC 1;
ecc2=rNFECC2;
/* 讀取該頁的OOB 塊 */
for(i=0;i< 16;i++)
{
se[i]=NF_RDDATA();
}
NF_nFCE_H(); /* 取消Nand Flash 選中*/
/* 校驗 ECC 碼, 並返回 */
if(ecc0==se[0] && ecc 1==se[1] && ecc2==se[2])
return 1;
else
return 0;
}
(3)flash程式設計
命令:
80h——10h :寫單頁;
80h——11h :對多個層進行些頁操作;
操作步驟:
1、寫單頁步驟:
【1】發出80h命令後;
【2】傳送4個地址序列;
【3】向flash傳送資料;
【4】發出命令10h啟動寫操作,flash內部自動完成寫、校驗操作;
【5】通過命令70h讀取狀態位,查詢寫操作是否完成;
2、多頁寫
【1】發出80h、4個地址序列、最多528位元組的資料;
【2】發出11h命令;
【3】接著在相鄰層執行【1】、【2】兩步操作;
【4】第四頁的最後使用10h代替11h,啟動flash內部的寫操作;
【5】可以通過71h查詢寫操作是否完成;
以頁為單位寫入.
引數說明:block 塊號
page 頁號
buffer 指向記憶體中待寫入Nand flash 中的資料起始位置
返回值: 0 :寫錯誤
1:寫成功
static int NF_WritePage(unsigned int block, unsigned int page, unsigned char *buffer)
{
int i;
unsigned int blockPage = (block<<5)+page;
unsigned char *bufPt = buffer;
NF_RSTECC(); /* 初始化 ECC */
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x0); /* 從A 區開始寫 */
NF_CMD(0x80); /* 寫第一條命令 */
NF_ADDR(0); /* A0~A7 位(Column Address) */
NF_ADDR(blockPage&0xff); /* A9A 16, (Page Address) */
NF_ADDR((blockPage>>8)&0xff); /* A17A24, (Page Address) */
NF_ADDR((blockPage>> 16)&0xff); /* A25, (Page Address) */
for(i=0;i<512;i++)
{
NF_WRDATA(*bufPt++); /* 寫一個頁512 位元組到 Nand Flash 晶片 */
}
/*
* OOB 一共16 Bytes, 每一個位元組存放什麼由程式設計師自己定義, 通常,
* 我們在 Byte0Byte2 存 ECC 檢驗碼. Byte6 存放壞塊標誌.
*/
seBuf[0]=rNFECC0; /* 讀取 ECC 檢驗碼 0 */
seBuf[1]=rNFECC 1; /* 讀取 ECC 檢驗碼 1 */
seBuf[2]=rNFECC2; /* 讀取 ECC 檢驗碼 2 */
seBuf[5]=0xff; /* 非壞塊標誌 */
for(i=0;i< 16;i++)
{
NF_WRDATA(seBuf [i]); /* 寫該頁的OOB 資料塊 */
}
NF_CMD(0x10); /* 結束寫命令 */
/* 等待Nand Flash 處於準備狀態 */
for(i=0;i< 10;i++);
NF_WAITRB();
/* 傳送讀狀態命令 Nand Flash */
NF_CMD(0x70);
for(i=0;i<3;i++);
if (NF_RDDATA()&0x1)
{ /*如果寫有錯, 則標示為壞塊 */
NF_nFCE_H(); /* 取消Nand Flash 選中*/
NF_MarkBadBlock(block);
return 0;
} else { /* 正常退出 */
NF_nFCE_H(); /* 取消Nand Flash 選中*/
return 1;
}
}
(4)複製
命令:
00h——8Ah——10h :單層頁內複製
03h——8Ah——11h :多層頁內複製
操作步驟:
1、單層頁內複製步驟:
【1】發出命令00h;
【2】4個源地址序列;
【2】接著發出8Ah;
【4】發出4個目的地址序列;
【5】發出10h命令,啟動寫操作;
【6】通過70h命令讀取狀態查詢操作是否完成;
2、多層頁內複製步驟:
【1】發出命令00h(第一層)、4個源頁地址序列;
【2】以後各層依次發出命令03h、4個源頁地址序列;
【3】發出命令8Ah、目的地址、命令11h;
【4】各層依次執行【3】,在最後一頁的地址後,用10h代替11h,啟動寫操作;
【5】通過71h命令讀取狀態查詢操作是否完成;
(5)擦除
命令:
60h——D0h :單層內塊擦除
60h-60h ——D0h :多層內塊擦除
操作步驟:
1、單層內塊擦除:
【1】發出命令字60h;
【2】發出塊(block)地址,僅需3個地址序列;
【3】發出D0h,啟動擦除操作;
【4】發出70h命令查詢狀態,是否完成擦除;
2、多層內塊擦除:
【1】發出命令字60h,3個塊地址序列;
【2】對每個層執行【1】;
【3】發出命令D0h,啟動擦除操作;
【4】發出71h命令查詢狀態,檢查是否完成擦除;
(6)讀取晶片ID
命令:90h
操作步驟:
1、發出命令90h;
2、發出4個地址序列(均設為0);
3、連續讀入5個數據,分別表示:廠商程式碼、裝置程式碼、保留位元組、多層操作程式碼;
返回值為Nand flash 晶片的 ID 號
unsigned short NF_CheckId(void)
{
int i;
unsigned short id;
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x90); /* 傳送讀ID 命令到 Nand Flash 晶片 */
NF_ADDR(0x0); /* 指定地址 0x0 ,晶片手冊要求 */
for(i=0;i< 10;i++); /* 等待tWB = 100ns. */
id=NF_RDDATA()<<8; /* 廠商ID(K9S 1208V:0xec) */
id|=NF_RDDATA(); /* 裝置 ID(K9S 1208V:0x76) */
NF_nFCE_H(); /* 取消Nand Flash 選中*/
return id;
}
(7)讀狀態
命令:
70h——單層狀態
71h——多層狀態
操作步驟:寫入命令字之後,然後啟動讀操作即可讀入此暫存器。
(8)Nand flash 標記壞塊
如果是壞塊, 通過寫 OOB 塊的Byte6 把該塊標記為壞塊。
引數說明:block 塊號
返回值:1:ok ,成功完成標記。
0 :表示寫OOB 塊正確.
static int NF_MarkBadBlock(unsigned int block)
{
int i;
unsigned int blockPage=(block<<5);
seBuf[0]=0xff;
seBuf[1]=0xff;
seBuf[2]=0xff;
seBuf[5]=0x44; /* 設定壞塊標記 */
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x50); /* 從C 區開始寫 */
NF_CMD(0x80); /* 傳送程式設計命令, 讓Nand Flash 處理寫狀態 */
NF_ADDR(0x0); /* A0~A7 位(Column Address) */
NF_ADDR(blockPage&0xff); /* A9A 16, (Page Address) */
NF_ADDR((blockPage>>8)&0xff); /* A17A24, (Page Address) */
NF_ADDR((blockPage>> 16)&0xff); /* A25, (Page Address) */
/* 寫OOB 資料塊 */
for(i=0;i< 16;i++)
{
NF_WRDATA(seBuf [i]);
}
NF_CMD(0x10); /* 結束寫命令 */
/* 等待NandFlash 準備好 */
for(i=0;i< 10;i++); /* tWB = 100ns. */
NF_WAITRB();
/*讀NandFlash 的寫狀態 */
NF_CMD(0x70);
for(i=0;i<3;i++); /* twhr=60ns */
if (NF_RDDATA()&0x1)
{
NF_nFCE_H(); /* 取消Nand Flash 選中*/
return 0;
} else {
NF_nFCE_H(); /* 取消Nand Flash 選中*/
}
return 1;
}
(9)Nand Flash 檢查壞塊
檢查指定塊是否是壞塊.
引數說明:block :塊號
返回值:1:指定塊是壞塊
0 :指定塊不是壞塊。
static int NF_IsBadBlock(U32 block)
{
int i;
unsigned int blockPage;
U8 data;
blockPage=(block<<5);
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x50); /* Read OOB 資料塊 */
NF_ADDR(517&0xf); /* A0~A7 位(Column Address) */
NF_ADDR(blockPage&0xff); /* A9A 16, (Page Address) */
NF_ADDR((blockPage>>8)&0xff); /* A17A24, (Page Address) */
NF_ADDR((blockPage>> 16)&0xff); /* A25, (Page Address) */
/* 等待NandFlash 準備好 */
for(i=0;i< 10;i++); /* wait tWB(100ns) */
NF_WAITRB();
/* 讀取讀出值 */
data=NF_RDDATA();
NF_nFCE_H(); /* 取消Nand Flash 選中*/
/* 如果data 不為0xff 時, 表示該塊是壞塊 */
if(data != 0xff)
return 1;
else
return 0;
}
(10)擦除指定塊中資料
引數說明:block 塊號
返回值:0 :擦除錯誤。(若是壞塊直接返回0 ;若擦除出現錯誤則標記為壞塊然後返回0)
1 :成功擦除。
static int NF_EraseBlock(unsigned int block)
{
unsigned int blockPage=(block<<5);
int i;
/* 如果該塊是壞塊, 則返回 */
if(NF_IsBadBlock(block))
return 0;
NF_nFCE_L(); /* 片選 Nand Flash 晶片*/
NF_CMD(0x60); /* 設定擦寫模式 */
NF_ADDR(blockPage&0xff); /* A9A 16, (Page Address) , 是基於塊擦*/
NF_ADDR((blockPage>>8)&0xff); /* A17A24, (Page Address) */
NF_ADDR((blockPage>> 16)&0xff); /* A25, (Page Address) */
NF_CMD(0xd0); /* 傳送擦寫命令, 開始擦寫 */
/* 等待NandFlash 準備好 */
for(i=0;i< 10;i++); /* tWB(100ns) */
NF_WAITRB();
/* 讀取操作狀態 */
NF_CMD(0x70);
if (NF_RDDATA()&0x1)
{
NF_nFCE_H(); /* 取消Nand Flash 選中*/
NF_MarkBadBlock(block); /* 標記為壞塊 */
return 0;
} else {
NF_nFCE_H(); /* 取消Nand Flash 選中*/
return 1;
}
}
相關推薦
Nand Flash介紹和Nand Flash控制器使用
一、Flash介紹 常用的flash型別有NOR Flash 和Nand Flash 兩種; (1)Nor Flash 1、Nor Flash的介面和RAM完全相同,可以隨機訪問任意地址的資料,在其上進行讀操作的效率非常高,但是擦除和寫操作的效率很低
S3C2440從NAND Flash啟動和NOR FLASH啟動的問題
### 1.為什麼NAND FLASH不能直接執行程式 NAND FLASH本身是連線到了控制器上而不是系統總線上。**CPU執行機制為:CPU啟動後是要取指令執行的**,如果是SROM、NOR FLASH 等之類的,CPU 通過地址線發個地址就可以取得指令並執行,NAND FLA
NAND Flash和 NOR Flash的區別
ROM和RAM指的都是半導體儲存器,ROM是ReadOnly Memory的縮寫,RAM是RandomAccess Memory的縮寫。ROM在系統停止供電的時候仍然可以保持資料,而RAM通常都是在掉電之後就丟失資料,典型的RAM就是計算機的記憶體。RAM有兩大類,一種稱為靜態RAM(Static
NOR flash 和NAND flash區別深入分析
快閃記憶體晶片讀寫的基本單位不同 應用程式對NOR晶片操作以“字”為基本單位。為了方便對大容量NOR快閃記憶體的管理,通常將NOR快閃記憶體分成大小為128KB或者64KB的邏輯塊,有時候塊內還分成扇區。讀寫時需要同時指定邏輯塊號和塊內偏移。應用程式
NOR flash和NAND flash的區別
最近學習flash時,說W25Q64是NOR flash。這個NOR flash和NAND flash的概念一直搞不清,下面是查詢的相關資料。 1、結構方面: NORflash採用記憶體的隨機讀取技術。各單元之間是並聯的,對儲存單元進行統一編址,
DM36x使用串列埠和NAND啟動完成NAND Flash燒寫(一)
背景:專案進行到最後階段,所有的啟動都需要放到NAND Flash晶片上。但是由於硬體設計,沒有新增網路和JTAG模組,所以常見的NFS和JTAG燒寫方式失效。於是,我們需要尋找可行的燒錄方式。 平臺: 作業系統:Ubuntu 10.04 開發板:DM36
SDRAM和NAND Flash的幾個注意點
1、首先CPU向SDRAM傳送一個讀地址,A0-A14對應的地址訊號是001000000000000b,此時SDRAM上的A0-A12上的地址訊號是0010000000000b,然後SDRAM返回該地址對應的儲存單元的資料(32位資料),最後儲存器控制器將該資料的低8位資料返回給CPU; 2、CPU向SDR
NAND flash和NOR flash的區別
一、NAND flash和NOR flash的效能比較flash快閃記憶體是非易失儲存器,可以對稱為塊的儲存器單元塊進行擦寫和再程式設計。任何flash器件的寫入操作只能在空或已擦除的單元內進行,所以大多數情況下,在進行寫入操作之前必須先執行擦除。NAND器件執行擦除操作是
nor flash 和nand flash 傻傻分不清楚
nor flash和nand flash區別 學習嵌入式有一段時間了,剛接觸nor和nand時很是迷惑,非要逼我寫一篇部落格才能記清楚。 首先他們都是儲存裝置,統稱叫做flash memory,導致他們存在差異的原因肯定是硬體上的差異了。//好似男人和女人,先有硬體的不同
UBIFS介紹 raw flash和MMC flash的區別
origin: http://sh.516878.com/2013/1101/25699.html 在瞭解UBIFS之前一定要注意UBIFS和任何傳統的檔案系統是不一樣的:UBIFS不是執行在block device之上的(比如hard disk, MMC/SD卡,USB
nor flash啟動與nand flash啟動的區別
1)介面區別: NOR FLASH地址線和資料線分開,來了地址和控制訊號,資料就出來。 NAND Flash地址線和資料線在一起,需要用程式來控制,才能出資料。 通俗的說,就是光給地址不行,要先命令,再給地址,才能讀到NAND的資料。而且都是在一個匯流排完成的。 結論是:A
SDN控制器之OVN實驗一:介紹和安裝OVN
OVN概覽 OVN是由開發出OVS的那群出色的程式設計師們的另一個優秀的作品。這個網路虛擬化專案從2015初宣告啟動,到不久前才釋出第一個正式版本OVN 2.6 。在這篇文章中,我會配置一個簡單示例:在三個主機之間配置一個layer-2 overlay網路。 首先講一下OVN工作機制中的2種
nandflash介紹和2440的nandflash控制器
1、Nand的型號與命名 以K9F2G08來示例分析一下:K9F表示是三星公司的NandFlash系列。2G表示Nand的大小是2Gbit(256MB)。08表示Nand是8位的(8位就是資料線有8根) 2.Nand的頁、塊、器件 Nand中可以被單次訪問的最小單元(就是說對Nand進行
8、svn版本控制器的介紹和window的安裝
學習目標: 1、瞭解什麼事版本控制系統 2、瞭解什麼是SVN 3、瞭解SVN的伺服器端的安裝 學習過程: 大家在寫程式碼的時候如果不小心誤刪了程式碼或者檔案,第二天後悔想要找回以前的程式碼的時候發現已經不可能找到了,還有如果在團體開發的時候如何可以更好的進行程式碼的共享和溝通呢,
ROM、RAM、IROM、IRAM、DRAM、SRAM、Flash介紹
1 ROM 、RAM、IROM、IRAM ROM:read only memory 只讀儲存器 ROM是指程式執行的過程中不能直接通過資料匯流排、地址匯流排進行資料的寫操作,必須藉助於相關的控制器介面來進行資料的寫操作。 ROM大部分對應著外部儲存器,主要是用來儲存永久性資料的,程式不能在其
嵌入式 Jlink中flash.csv和*.jflash檔案分析
轉自:點選開啟 本文是對《使用Jlink下載程式到Nor Flash》一文的補充和修正(尤其修正init sequence的內容)。 分析這兩個檔案的目的:是為了以後使用新的MCU和Flash時自己製作project檔案。當然可以在圖形介面配置這兩個檔案,但我還是習慣分析
【原創】【SPI】SPI Flash介紹
一、這是個什麼玩意首先它是個Flash,Flash是什麼東西就不多說了(非易失性儲存介質),分為NOR和NAND兩種(NOR和NAND的區別本篇不做介紹)。SPI一種通訊介面。那麼嚴格的來說SPI Flash是一種使用SPI通訊的Flash,即,可能指NOR也可能是NAND。
人形時鐘,和倉鼠flash
<div height="120" width="150" align="center"><embed height="120" width="150" type="applicat
STM32操作訪問flash,包括寫入資料到flash和從flash讀取資料
STM32中儲存區分為:隨機存取儲存器RAM和只讀儲存器ROM。 其中: RAM為常說的記憶體,比如手機的2G記憶體4G記憶體等,就是程式跑起來的時候所佔用的儲存空間,特點是掉電資料丟失。 ROM為常說的硬碟,比如手機的64G和128G等,可以簡單的理解為
S3C2416 SD卡啟動和NAND啟動的配置
S3C2416的啟動方式分為IROM、NAND、ONENAND/ROM三種模式,有的datasheet上只有IROM、ONENAND/ROM兩種模式,如下圖所示: