Ⅰ、寫在前面
寫這篇文章的目的有兩點:1.讓大家知道SPI在實際應用開發中的重要意義; 2.讓大家掌握SPI FLASH存儲芯片的時序及驅動編程。
市面上的SPI FLASH類型很多,但是絕大部的芯片在硬件和軟件上都是兼容的。雖然本文是以華邦的W25X16芯片為例來講述時序。其實,其它大部分SPI FLASH都適用。
有必要看芯片手冊,按照手冊一步一步寫程序嗎?
1、如果你是初學者,而且還有很多時間,建議花些時間掌握一下! 原因在于作為嵌入式開發者,需要對芯片的編程有一定了解,在以后工作項目中如果有使用新的芯片,自己就能很容易編寫驅動(如果沒有現成的驅動)。
2、如果你是工作了一斷時間,自己對芯片驅動編程有一些經驗,在需要使用新的芯片,如果有現成的、比較成熟的驅動,那么,你可以不用再話費時間自己親自編寫驅動(編寫驅動很費時間,還需要花費一定時間驗證)。
關于本文的更多詳情請往下看。
Ⅱ、實例工程下載
筆者針對于初學者提供的例程都是去掉了許多不必要的功能,精簡了官方的代碼,對初學者一看就明白,以簡單明了的工程供大家學習。
筆者提供的實例工程都是在板子上經過多次測試并沒有問題才上傳至360云盤,歡迎下載測試、參照學習。
提供下載的軟件工程是基于Keil(MDK-ARM) V5版本、STM32F103ZE芯片,但F1其他型號也適用(適用F1其他型號: 關注微信,回復“修改型號”)。
STM32F10x_SPI(硬件接口)讀寫Flash(25Q16)實例源代碼工程:
https://yunpan.cn/c6mfRJWva6AJ2訪問密碼 4bc4
STM32F10x_SPI(軟件模擬)讀寫Flash(25Q16)實例源代碼工程:
https://yunpan.cn/c6mf6zyzCaMwd訪問密碼 cf45
SPI FLASH資料:
https://yunpan.cn/c6Yi3agWUnGNQ訪問密碼 d790
STM32F1資料:
https://yunpan.cn/crBUdUGdYKam2訪問密碼 ca90
Ⅲ、關于SPIFLASH
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)、 可整個芯片擦除。
Ⅳ、SPIFLASH時序及編程
這里還是以華邦的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芯片所有的指令,其他廠家芯片或許還有一些指令,請根據情況看手冊編寫相應代碼。
-
FlaSh
+關注
關注
10文章
1621瀏覽量
147749 -
驅動
+關注
關注
12文章
1825瀏覽量
85178 -
SPI
+關注
關注
17文章
1700瀏覽量
91319
發布評論請先 登錄
相關推薦
評論