1. 程式人生 > >SPI_FLASH時序描述及驅動程式設計

SPI_FLASH時序描述及驅動程式設計

Ⅰ、寫在前面

前面文章講述過關於SPI的驅動(硬體SPI 和 軟體模擬SPI),本文接著那篇文章來講述關於SPI應用中【FLASH時序描述及驅動程式設計】

寫這篇文章的目的有兩點:1.讓大家知道SPI在實際應用開發中的重要意義; 2.讓大家掌握SPI FLASH儲存晶片的時序及驅動程式設計。

市面上的SPI FLASH型別很多,但是絕大部的晶片在硬體軟體上都是相容的。雖然本文是以華邦的W25X16晶片為例來講述時序。其實,其它大部分SPI FLASH都適用。

有必要看晶片手冊,按照手冊一步一步寫程式嗎?

1、如果你是初學者,而且還有很多時間,建議花些時間掌握一下! 原因在於作為嵌入式開發者,需要對晶片的程式設計有一定了解,在以後工作專案中如果有使用新的晶片,自己就能很容易編寫驅動(如果沒有現成的驅動)。

2、如果你是工作了一斷時間,自己對晶片驅動程式設計有一些經驗,在需要使用新的晶片,如果有現成的、比較成熟的驅動,那麼,你可以不用再話費時間自己親自編寫驅動(編寫驅動很費時間,還需要花費一定時間驗證)。

關於本文的更多詳情請往下看。

Ⅱ、例項工程下載

筆者針對於初學者提供的例程都是去掉了許多不必要的功能,精簡了官方的程式碼,對初學者一看就明白,以簡單明瞭的工程供大家學習。

筆者提供的例項工程都是在板子上經過多次測試並沒有問題才上傳至360雲盤,歡迎下載測試、參照學習。

提供下載的軟體工程是基於Keil(MDK-ARM) V5版本、STM32F103ZE晶片,但F1其他型號也適用(適用F1其他型號: 關注微信,回覆“修改型號”)。

STM32F10x_SPI(硬體介面)讀寫Flash(25Q16)例項原始碼工程:

STM32F10x_SPI(軟體模擬)讀寫Flash(25Q16)例項原始碼工程:

SPI FLASH資料:

STM32F1資料:

Ⅲ、關於SPI FLASH

1.SPI FLASH晶片系列

SPI FLASH的種類及型號有很多,但根據筆者的瞭解及經驗,雖然存在這些差異,但他們之間的相容性是很好的。

如:W25Xxx系列、W25Qxx系列、GD25Qxx系列、M25Pxx系列、KM25Lxx系列、SST25VFxx系列、AT25F系列等。

2.SPI FLASH

命名

每一家公司的晶片型號命名可能略有差異,但看手冊就能明白。我們以華邦的W25系列晶片來舉例說明:

W:代表華邦公司

25X:代表SPI FLASH型別(25X是基本晶片, 25Q是快速晶片)

16:代表16MBit,即2M位元組(64代表8M位元組, 128代表16M位元組,依次下去)

這個需要大家瞭解的(主要在專案研發初級階段對晶片的選型上使用到)。其他公司的晶片,檢視方法類似.對比如圖是ST公司的M25PExx系列晶片:

3.W25Xxx讀寫特性

讀:無要求

寫:需要擦除才能寫,一次最多可寫入256位元組(可程式設計頁)。

擦除:最小扇區擦除(4K)、可塊擦除(64K)、 可整個晶片擦除。

Ⅳ、SPI FLASH時序及程式設計

這裡還是以華邦的W25X16為例來說明(其他大部分相容),請下載手冊【W25Xxx手冊(英文版)】參考。

1.預先了解W25Xxx

A.控制和狀態暫存器命令(預設:0x00)

BIT位  7   6   5   4   3   2   1   0

      SPR  RV  TB  BP2 BP1 BP0 WEL BUSY

SPR:預設0,狀態暫存器保護位,配合WP使用

TB,BP2,BP1,BP0:FLASH區域防寫設定

WEL:寫使能鎖定

BUSY:忙標記位(1,忙;0,空閒)

B.指令集表

程式設計主要就圍繞這些“指令”來程式設計。在我提供的軟體工程程式碼“sflash.h”檔案中就定義了和手冊對應的指令,如下圖:

2.寫使能(0x06)

在操作(控制、資料)之前,都需要傳送一條“寫使能”指令。

時序如下圖

原始碼程式:

3.寫失能(0x04)

和“寫使能”類似,要失能寫,在操作(控制、資料)之後,都需要傳送一條“寫失能”指令。

時序如下圖

原始碼程式:

4.讀狀態/控制(0x05)

W25X晶片唯一的狀態暫存器,各個位的意思請看上面的介紹,比如判斷忙不忙,就需要讀狀態。

時序如下圖

原始碼程式:

5.寫狀態/控制(0x01)

寫狀態/控制 和 讀狀態/控制類似。

時序如下圖

原始碼程式:

6.讀資料(0x03)

這個就是我們重要的讀資料指令。1.寫入指令0x03; 2.寫入24位地址; 3.連續讀出N位元組資料(只要有時鐘,可以連續讀出多位元組);

時序如下圖

原始碼程式:

7.快速讀資料(0x0B)

“快速讀資料”和“讀資料”類似,但它的區別:1.讀資料速度更快; 2.需要在寫入地址之後需要8個時鐘的等待。

1.寫入指令0x0B; 2.寫入24位地址; 3.寫入8個時鐘; 4.連續讀出N位元組資料(只要有時鐘,可以連續讀出多位元組);

時序如下圖

原始碼程式:

8.快速雙通道讀資料(0x3B)

“快速雙通道讀資料”和“快速讀資料”類似,但它的區別:在讀資料的時候是兩條通道,也就是我們平時主機的輸出引腳(MOSI)在這個時候拿來當做輸入引腳讀資料。

注意:

使用該指令功能,需要改變SPI底層驅動(即需要改變MOSI引腳的輸入輸出狀態)。針對初學者,我提供的工程也沒有寫的那麼複雜,即該指令功能沒有(感興趣的朋友可研究一下)。

9.寫資料(頁程式設計)(0x02)

“寫資料”和“讀資料”類似,但寫資料都是在同一條資料(DIO)線上,讀資料在地址之後是在DO資料上。

1.寫入指令0x02; 2.寫入24位地址; 3.連續寫入N位元組資料(只要有時鐘,可以連續寫入多位元組,注意這裡一次不能超過256位元組資料);

時序如下圖

原始碼程式:

10.塊擦除(0xD8)

W25Xxx塊的多少有晶片型號決定,一塊資料大小64K。

W25X16共2M位元組,有16塊(2M/64K = 16)

W25X64共8M位元組,有64塊(8M/64K = 64)

以此類推...

注意:這個塊的地址是和資料的地址對應,我們程式塊擦除中將塊區分開來。

時序如下圖

原始碼程式:

11.扇區擦除(0x20)

W25Xxx扇區的多少有晶片型號決定,扇區資料大小4K。

W25X16共2M位元組,有256塊(2M/4K = 256)

W25X64共8M位元組,有1024塊(8M/4K = 1024)

以此類推...

同樣,我們程式扇區擦除中將扇區以扇區的形式區分開來。

時序如下圖

原始碼程式:

12.晶片擦除(0xC7)

這條指令是擦除整個晶片內容,如果要繼續操作晶片,需要等待擦除完成(檢查忙訊號)。

時序如下圖

原始碼程式:

13.掉電(低功耗)(0xB9)

需要將晶片處於低功耗,傳送該指令。

時序如下圖

原始碼程式:

14.喚醒/ID(0xAB)

該指令有兩個功能:1.將處於低功耗的晶片喚醒(常用); 2.讀取裝置ID(不常用)。

傳送該指令可以將晶片喚醒,繼續傳送3位元組無效資料,可繼續讀出裝置ID.由於讀取裝置ID有單獨的指令,這裡基本不常用於讀裝置ID(程式中也沒有該功能)。

時序如下圖

原始碼程式:

15.讀取ID(0x90)

這個指令讀取兩位元組資料(ID):高位元組是廠家Manufacturer,低位元組是晶片型號ID.

如我開發板上是W25Q128,讀到的ID是:0XEF17

W25X16讀到的ID是:EF14

時序如下圖

原始碼程式:

16.JEDEC_ID(0x9F)

出於相容性考慮,有些晶片廠家使用該指令讀取ID,這條指令和上一條指令類似。

與上一條指令不同點:1.不用傳送3位元組無效資料;  2.讀出來的ID是3位元組(依次是:廠家ID、批次ID、型號ID)。

時序如下圖

原始碼程式:

以上就是關於W25Xxx晶片所有的指令,其他廠家晶片或許還有一些指令,請根據情況看手冊編寫相應程式碼。

Ⅴ、說明

本文主要是為初學者提供一個程式設計的思路,及如何根據時序程式設計。

以上總結僅供參考,若有不對之處,敬請諒解。

、最後

更多精彩文章我將第一時間在微信公眾號裡面分享,該文有什麼疑問可留言。

本著免費分享的原則,方便大家手機學習知識,定期在微信平臺分享技術知識。如果你覺得分享的內容對你有用,又想了解更多相關的文章,請用微信搜尋“EmbeddDeveloper” 或者掃描下面二維碼、關注,將有更多精彩內容等著你。