NOR Flash的原理與操作


學習目標:

1、了解nor flash存儲芯片的概念和特性

2、掌握使用s3c2440芯片對外掛的nor flash進行讀寫擦除操作


1、NOR Flash的簡單介紹

NOR Flash最早是由Intel公司於1988年開發出的,是現在市場上兩種主要的非易失性存儲器之一,它的出現徹底改變了存儲器市場上由EPROM(Erasable Programmable Read-Only-Memory電可編程序只讀存儲器)和EEPROM(電可擦只讀存儲器Electrically Erasable Programmable Read - Only Memory)一統天下的局面。NOR Flash最大特點是支持XIP(Execute On Chip),既程序可以直接在NOR flash的片內執行,在NOR Flash中的代碼運行時不需要重定位復制到RAM內。NOR Flash的地址線和數據線分開,數據的讀取和RAM很類似,只要能夠提供數據地址,數據總線就能正確給出數據。不過不能直接對它進行寫操作,執行寫操作之前需要先發送固定的命令序列,然后發送寫操作的地址和數據。

NOR Flash存儲器的最小訪問單元一般分為8位和16位的,也有一些NOR Flash器件同時支持8位和16位模式,這種Flash的位寬可以在設計硬件時選擇,當芯片的BYTE#引腳接為高電平,芯片工作在位寬16位模式,BYTE#引腳設為低電平時,芯片工作在位寬8位模式。

NOR Flash一般有多個扇區,扇區是NOR Flash擦除的最小單位,Nor Flash中每個扇區的大小也不是固定的,扇區的排放一般分為兩種模式Top Boot part 和Bottom Boot part 。這兩種形式的區別是小塊的扇區在NOR Flash芯片中放置的位置不同,Bottom Boot類型的NOR Flash小塊地址位於芯片0地址,而Top Boot part類型的NOR Flash小塊地址位於芯片的高地址上。

2、NOR Flash引腳介紹(以MX29LV60DBTI芯片為例)

MX29LV60DBTI是16M-BIT的NOR Flash芯片,它的引腳如下圖所示:

引腳描述表

符號 管腳名 功能
A0~A19 地址輸入 地址信號,表示要讀寫數據的地址信息
Q0~Q15 數據輸入/輸出 數據輸入/輸出引腳,讀周期內輸出數據,寫周期內輸入數據
CE# 芯片使能 CE#為低電平時,芯片被選中,后續執行的操作才會有效
WE# 寫使能 配合CE#和OE#以及地址引腳和數據引腳一起使用,當CE#低電平,OE#高電平,WE#為低電平時,Q0~Q15上數據被寫入到A0~A19表示地址中
BYTE# 字或字節選擇輸入 當其為高電平時,數據輸出為16bit模式;低電平時,數據輸出為8bit模式
RESET# 硬件復位/扇區保護解鎖引腳 硬件復位引腳,當輸入信號為低電平時,芯片復位
OE# 輸出使能 配合CE#和WE#以及地址引腳和數據引腳一起使用,當CE#低電平,WE#高電平,OE#為低電平時,將地址A0~A19內存中的數據傳送到Q0~A15上
RY/BY#  RY/BY#輸出引腳 用於輸出Ready和Busy信號,實際用時可以不接,可以用命令查詢NOR Flash狀態代替
VCC 電源供應引腳(2.7v~3.6v) 芯片供電電源
GND 地引腳 芯片電源地
WP#/ACC 硬件寫保護/加速引腳 硬件寫保護引腳,低電平有效
NC 不連接內部引腳 不用連接

3、NOR Flash於S3C2440連接圖

NOR Flash的數據寬度是16位的,與2440處理器的連接時,地址線必須錯位進行連接。s3c2440的地址線A0懸空,A1連接NOR Flash的地址線A0,A2連接NOR Flash的地址線A1,依次排序。需要錯位連接的原因是:2440處理器的每個地址對應的是一個BYTE 的數據單元,而 16-BIT 的 NOR FLASH 的每個地址對應的是一個HALF-WORD(16-BIT)的數據單元。為了保持匹配,所以必須錯位連接。這樣,從2440處理器發送出來的地址信號的最低位A0對16-BIT FLASH來說就被屏蔽掉了。

上面的描述過程太過抽象了,下面通過畫圖來解釋錯位連接的原因:

①、ARM處理器需要從地址0x0讀取一個BYTE

  1. ARM處理器在地址線An-A0上送出信號0x0;
  2. 由於2440的A1連接NOR Flash A0,16-BIT FLASH在自己的地址信號An-A0上看到的地址是0x0,然后將地址0x0對應的16-BIT數據單元輸出到D15-D0上;
  3. ARM處理器知道訪問的是16-BIT的FLASH,從D7-D0上讀取所需要的一個BYTE的數據。

②、ARM處理器需要從地址0x1讀取一個BYTE

  1. ARM處理器在地址線An-A0上送出信號0x1;
  2. 由於2440的A1連接NOR Flash A0,16-BIT FLASH在自己的地址信號An-A0上看到的地址依然是0x0, 然后將地址0x0對應的16-BIT數據單元輸出到D15-D0上;
  3. ARM處理器知道訪問的是16-BIT的FLASH,從D15-D8 上讀取所需要的一個BYTE 的數據。

注意:有些ARM處理器內部可以設置地址的錯位。對於支持軟件選擇地址錯位的處理器,在連接16-BIT FLASH的時候,硬件上不需要把地址線錯位。在設計的時候,應該參考芯片的數據手冊,以手冊為准,以免造成不必要的麻煩(如stm32連接是A0~A0)。

4、S3C2440驅動NOR Flash時序配置

 s2c2440內存控制器接讀NOR Flash時序圖

上圖為s3c2440操作NOR Flash的讀時序,Tacs表示片選使能前地址信號的設置時間(既地址信號需要設置多久,才能使能片選信號),Tcos表示OE#信號使能前片選使能的設置時間,Tacc表示數據的訪問周期,Tcoh表示OE#信號釋放后片選信號的保持時間,Tcah表示片選信號釋放后地址信號的保持時間。由於s3c2440為通用性能的處理器,他的外部可能接不同公司生成的不同型號的NOR Flash,所以這些參數值要根據所接型號的NOR Flash的時序圖進行設置。

下面根據NOR Flash芯片MX29LV60DBTI時序圖來配置上述參數,MX29LV60DBTI的時序圖如下圖所示:

NOR Flash芯片MX29LV60DBTI讀操作內部時序圖

NOR Flash芯片MX29LV60DBTI時序圖各參數具體值

Tce:片選信號使能后多久輸出數據有效,最大值為70ns

Toe:讀信號發出后多久輸出數據有效,最大值為30ns

Taa:地址信號發出后數據有效,最大值為70ns

Trc:讀周期時間,最小70ns

Tdf:OE#或CE#高時,數據引腳浮空時間,最大30ns(可以忽略設置,當讀取數據結束后,新的讀取信號發出,要過70ns,數據線上數據有效,這段引腳浮空時間無影響)

上述最大值表示發出該信號后,間隔最大值的時間后,數據引腳的信號一定是有效的,在這個范圍之內,數據信號的引腳可能有效。

為簡單,我們一般設置2440的CE#、OE#、ADD控制信號同時發出,保持70ns后進行讀取數據引腳的數據。NOR Flash連接s3c2440的Bank0地址,配置時序的寄存器為BANKCON0,該寄存器的各個位如下圖所示:

內存控制器的時鍾信號由HCLK時鍾信號提供,假設設置的HCLK的值為100M,1clock = 10ns。根據前面分析,Tacs、Tcos寄存器位設置為0,Tacc寄存器的為設置為101 = 8clocks。

5、NOR Flash的讀操作

NOR Flash是類似於內存類的接口,讀操作和內存的讀取一樣,直接發送相應的地址便能獲取相應數據

unsigned int nor_read_word(unsigned int base, unsigned int offset)
{
    volatile unsigned short *p = (volatile unsigned short *)(base + offset);
    return *p;
}

unsigned int nor_dat(unsigned int offset)
{
    return nor_read_word(NOR_FLASH_BASE, offset);
}

6、NOR Flash的扇區擦除

擦除NOR Flash扇區時,應先發送相應的命令,發送命令的順序如下:

第1個總線周期:往555地址中寫入AA

第2個總線周期:往2AA地址中寫入55

第3個總線周期:往555地址中寫入80

第4個總線周期:往555地址中寫入AA

第5個總線周期:往2AA地址中寫入55

第6個總線周期:往要擦除的扇區寫入30

void nor_write_word(unsigned int base, unsigned int offset, unsigned int val)
{
    volatile unsigned short *p = (volatile unsigned short *)(base + offset);
    *p = val;
}

/* offset是基於cpu的角度看到 */
void nor_cmd(unsigned int offset, unsigned int cmd)
{
    nor_write_word(NOR_FLASH_BASE, offset, cmd);
}

/* 等待燒寫完成 : 讀數據, Q6無變化時表示結束 */
void wait_ready(unsigned int addr)
{
    unsigned int val;
    unsigned int pre;

    pre = nor_dat(addr);
    val = nor_dat(addr);
    while ((val & (1<<6)) != (pre & (1<<6)))
    {
        pre = val;
        val = nor_dat(addr);        
    }
}
void erase_nor_flash_sector(unsigned int addr)
{
    printf("erasing ...\n\r");
    nor_cmd(0x555<<1, 0xaa);    /* 解鎖 */
    nor_cmd(0x2aa<<1, 0x55); 
    nor_cmd(0x555<<1, 0x80);     /* erase sector */
    
    nor_cmd(0x555<<1, 0xaa);    /* 解鎖 */
    nor_cmd(0x2aa<<1, 0x55); 
    nor_cmd(addr, 0x30);     /* 發出扇區地址 */
    wait_ready(addr);  /* 等待操作完成 */
}

CPU外接NOR Flash,實際上就是將NOR Flash地址映射為CPU的統一編址。由於nor_cmd函數的offset是基於CPU的角度看到地址,而芯片手冊上NOR Flash寫入命令的地址從NOR Flash的實際物理地址,NOR Flash是16位的,它的0地址應該對應CPU的0地址和1地址。因此,NOR Flash的物理地址從CPU的角度來看,地址值應該是NOR Flash角度來看的兩倍,所以在向某地址寫入命令時,要將NOR Flash角度來看的地址右移一位。

7、NOR Flash的寫操作

向NOR Flash地址中寫入數據時,也應先發送相應的命令,發送命令的順序如下:

第1個總線周期:往555地址中寫入AA

第2個總線周期:往2AA地址中寫入55

第3個總線周期:往555地址中寫入A0

第4個總線周期:往要目標地址寫入數據

void write_nor_flash(unsigned int addr,unsigned int val)
{
    /* 燒寫 */
    nor_cmd(0x555<<1, 0xaa);     /* 解鎖 */
    nor_cmd(0x2aa<<1, 0x55); 
    nor_cmd(0x555<<1, 0xa0);     /* program */
    nor_cmd(addr, val);
    /* 等待燒寫完成 : 讀數據, Q6無變化時表示結束 */
    wait_ready(addr);
}

寫操作時值得注意的是,只有寫入的目標的地址內容為0xff時,數據才能正確的寫入,因此,一般情況下NOR Flash在寫入時要對扇區進行擦除操作。NOR Flash在寫入數據時只能將地址中的某位由1變0,而不能將某位由0變1。

假設NOR Flash某地址中存放字符a(0x61),如果未進行擦除前向該地址中寫入字符G(0x47),最后該地址內容為A(0x41)。原因如下:

  字符a化為二進制--->1100001

  字符G化為二進制--->1000111

       由於寫入時數據位只能由0變為1,最終結果100001,相當於執行原始數據和新寫入數據進行&操作

向NOR Flash執行上述步驟,驗證上述過程

①、向0x80000地址寫入a字符

②、未進行擦除扇區向0x80000地址寫入G字符,接着讀取這個地址里的數據,實際讀取內容為0x41,不是0x47,結果符合上面描述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM