如何通過軟件SPI讀寫W25Q64

STM32F1之SPI通信·軟件SPI代碼編寫-CSDN博客

目錄

1.? W25Qxx系列簡介

2.? W25Q64硬件電路

?3.??W25Q64框圖

4.? Flash操作注意事項

5.? 代碼編寫

5.1? 初始化

5.2??W25Q64讀取ID號

5.3??W25Q64寫使能

5.4??W25Q64等待忙

5.5??W25Q64頁編程

5.6??W25Q64扇區擦除(4KB)

5.7??W25Q64讀取數據


1.? W25Qxx系列簡介

????????W25Qxx系列是一種低成本、小型化、使用簡單的非易失性存儲器,常應用于數據存儲、字庫存儲、固件程序存儲等場景。

非易失性存儲器(Non-Volatile Memory, NVM)和易失性存儲器(Volatile Memory)的主要區別在于電源斷電后的數據保存能力:

  1. 非易失性存儲器(NVM)

    • 數據持久性:即使在斷電的情況下,數據也能保持不丟失。
    • 常見類型:閃存(如USB閃存盤、固態硬盤)、硬盤驅動器(HDD)、只讀存儲器(ROM)、磁帶等。
    • 應用場景:適用于需要長期保存數據的場合,如計算機硬盤、手機存儲、固態硬盤等。
  2. 易失性存儲器(Volatile Memory)

    • 數據持久性:在斷電時,存儲在其中的數據會丟失。
    • 常見類型:隨機存取存儲器(RAM),如動態隨機存取存儲器(DRAM)和靜態隨機存取存儲器(SRAM)。
    • 應用場景:適用于需要高速訪問數據但不需要長期保存的場合,如計算機的主內存(RAM)等。

存儲介質:Nor Flash(閃存)

時鐘頻率: 80MHz ;

? ? ? ? ? ? ? ? ? ?160MHz (Dual SPI)(雙重SPI);

? ? ? ? ? ? ? ? ? ?320MHz (Quad SPI)(四重SPI)。

存儲容量(24位地址):

W25Q40:?? ? ?4Mbit / 512KByte ?? ?

W25Q80:?? ? ?8Mbit / 1MByte ?? ?

W25Q16:?? ? ?16Mbit / 2MByte ?? ?

W25Q32:?? ? ?32Mbit / 4MByte ?? ?

W25Q64:?? ? ?64Mbit / 8MByte ?? ?

W25Q128: ?128Mbit / 16MByte ?? ?

W25Q256: ?256Mbit / 32MByte

2.? W25Q64硬件電路

引腳功能
VCC、GND電源(2.7V~3.6V)
CS(SS)SPI片選
CLK(SCK)SPI時鐘
DI(MOSI)SPI主機輸出從機輸入
DO(MISO)SPI主機輸入從機輸出
WP寫保護
HOLD數據保持

?3.??W25Q64框圖

4.? Flash操作注意事項

寫入操作時:

寫入操作前,必須先進行寫使能;

每個數據位只能由1改寫為0,不能由0改寫為1;

寫入數據前必須先擦除,擦除后,所有數據位變為1;

擦除必須按最小擦除單元進行 連續寫入多字節時,最多寫入一頁的數據,超過頁尾位置的數據,會回到頁首覆蓋寫入;

寫入操作結束后,芯片進入忙狀態,不響應新的讀寫操作。

讀取操作時:

直接調用讀取時序,無需使能,無需額外操作,沒有頁的限制,讀取操作結束后不會進入忙狀態,但不能在忙狀態時讀取

5.? 代碼編寫

5.1? 初始化

? ? ? ? 首先初始化SPI,可見本文頂部往期回顧鏈接,初始化SPI:

void W25Q64_Init(void)
{MySPI_Init();					//先初始化底層的SPI
}

5.2??W25Q64讀取ID號

? ? ? ? 對于下圖規格書,我們現將其進行宏定義:

#ifndef __W25Q64_INS_H
#define __W25Q64_INS_H#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3#define W25Q64_DUMMY_BYTE							0xFF#endif

? ? ? ? 找到其規格書,找到其框住的部分,可以看到其獲取ID的指令為9F,并且需要接收到3個字節,我們可以將其流程看做:起始、先交換發送指令9F、隨后連續交換接收3個字節、停止。

對于上面三個字節的解讀:

????????第一個字節是廠商的ID,表示是哪個廠家生產的。

? ? ? ? 第二個字節是設備ID,設備ID高八位,表示存儲器類型。

????????第三個字節也是設備ID,設備ID低八位,表示容量。

void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_JEDEC_ID);			//交換發送讀取ID的指令*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交換接收MID,通過輸出參數返回,其中括號內的數據可以為任何數,通常我們使用0xFF,目的是將有用的數據置換過來。*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交換接收DID高8位,其內數據同上*DID <<= 8;									//高8位移到高位*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//或上交換接收DID的低8位,通過輸出參數返回,其內數據同上,MySPI_Stop();								//SPI終止
}

????????? 其中,MID 工廠ID,使用輸出參數的形式返回,DID 設備ID,使用輸出參數的形式返回。

5.3??W25Q64寫使能

void W25Q64_WriteEnable(void)
{MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_WRITE_ENABLE);		//交換發送寫使能的指令MySPI_Stop();								//SPI終止
}

5.4??W25Q64等待忙

void W25Q64_WaitBusy(void)
{uint32_t Timeout;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);				//交換發送讀狀態寄存器1的指令Timeout = 100000;							//給定超時計數時間while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)	//循環等待忙標志位{Timeout --;								//等待時,計數值自減if (Timeout == 0)						//自減到0后,等待超時{/*超時的錯誤處理代碼,可以添加到此處*/break;								//跳出等待,不等了}}MySPI_Stop();								//SPI終止
}

5.5??W25Q64頁編程

void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{uint16_t i;W25Q64_WriteEnable();						//寫使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_PAGE_PROGRAM);		//交換發送頁編程的指令MySPI_SwapByte(Address >> 16);				//交換發送地址23~16位MySPI_SwapByte(Address >> 8);				//交換發送地址15~8位MySPI_SwapByte(Address);					//交換發送地址7~0位for (i = 0; i < Count; i ++)				//循環Count次{MySPI_SwapByte(DataArray[i]);			//依次在起始地址后寫入數據}MySPI_Stop();								//SPI終止W25Q64_WaitBusy();							//等待忙
}

5.6??W25Q64扇區擦除(4KB)

void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();						//寫使能MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);	//交換發送扇區擦除的指令MySPI_SwapByte(Address >> 16);				//交換發送地址23~16位MySPI_SwapByte(Address >> 8);				//交換發送地址15~8位MySPI_SwapByte(Address);					//交換發送地址7~0位MySPI_Stop();								//SPI終止W25Q64_WaitBusy();							//等待忙
}

5.7??W25Q64讀取數據

void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{uint32_t i;MySPI_Start();								//SPI起始MySPI_SwapByte(W25Q64_READ_DATA);			//交換發送讀取數據的指令MySPI_SwapByte(Address >> 16);				//交換發送地址23~16位MySPI_SwapByte(Address >> 8);				//交換發送地址15~8位MySPI_SwapByte(Address);					//交換發送地址7~0位for (i = 0; i < Count; i ++)				//循環Count次{DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//依次在起始地址后讀取數據}MySPI_Stop();								//SPI終止
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/14894.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14894.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/14894.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WebRTC | 網絡傳輸協議 RTP 和 RTCP

WebRTC | 網絡傳輸協議 RTP 和 RTCP WebRTC | 網絡傳輸協議 RTP 和 RTCP如何選擇 TCP 與 UDPRTP概述工作機制報文結構RTP 的使用RTP 拓展頭RTP 中的填充數據翻譯器和混合器同步控制報文大小wireshark 抓取 RTP 報文 RTCP概述工作機制分組類型報文結構WebRTC 的反饋報文RTPFBPSF…

深入淺出遞歸算法

文章目錄 遞歸思想遞歸的題目1.漢諾塔問題問題分析代碼展示 2.合并兩個有序鏈表問題分析代碼展示 3.反轉鏈表問題分析代碼展示 4.兩兩交換 鏈表中的節點問題分析代碼展示 總結 遞歸思想 遞歸就是將一個很大的問題拆分成子問題&#xff0c;然后再將子問題繼續拆分&#xff0c;拆…

經典正則表達式實例

1、由26個字母組成的字符串 ^[A-Za-z]$2、 由26個字母和數字組成的字符串 ^[A-Za-z0-9]$3、整數形式的字符串 ^-?\d$4、正整數形式的字符串 ^[0-9]*[1-9][0-9]*$5、中國境內郵政編碼,6位 [1-9\d{5}6、匹配中文字符 [\u4e00-\u9fa5]7、國內電話號碼,010-6872**** \d{3}-…

【linux-IMX6ULL-字符設備驅動簡單框架實驗】

目錄 1. 字符設備驅動簡介1.1 重要函數1.2 簡單框架代碼流程1.3 linux中關于驅動的重要命令 2. 字符設備驅動簡單框架編寫2.1 添加LICENSE信息2.2 驅動模塊的入口與出口2.3 入口和出口函數的編寫2.4 設備操作結構體定義2.4.1 結構體函數內容填充 3. 應用程序簡介&#xff1a;4.…

Design to code(2)

【碎碎念】從七點到十一點&#xff0c;累計用時4個小時完成的代碼翻譯Σ(&#xffe3;。&#xffe3;ノ)ノ DCDS圖 順序圖&#xff08;支付過程&#xff09; 交互圖&#xff08;訂單&#xff09; 我的代碼 Payment public class Payment { //定義支付訂單金額 private…

static的了解

【關鍵字】static 使用總結_c static關鍵字-CSDN博客 本文來自上面的文章&#xff0c;這里用于學習&#xff0c;謝謝大佬的分享&#xff01;&#xff01;&#xff01; 非原創&#xff01;&#xff01;&#xff01; 1.一個項目中創建main.cpp和demo.cpp &#xff08;1&#…

FL Studio2025中文最新版本專業編曲軟件有哪些新功能?

FL Studio 21&#xff0c;也被音樂制作愛好者親切地稱為“水果編曲軟件”&#xff0c;是比利時的Image-Line公司研發的一款完整的音樂制作環境或數字音頻工作站&#xff08;DAW&#xff09;。自從1990年代推出以來&#xff0c;FL Studio 以其直觀的用戶界面、豐富的插件支持和強…

Rust分割字符串的常見操作方法

在Rust編程語言中&#xff0c;分割字符串是一個常見的操作&#xff0c;可以通過多種方式實現。以下是一些常用的方法&#xff1a; 使用split方法&#xff1a; split方法可以按照指定的字符或字符序列來分割字符串。它返回一個迭代器&#xff0c;可以迭代分割后的字符串片段。 l…

玩機社區 - 2024年最美社區源碼開源

玩機社區 - 2024年最美社區源碼開源 教程源碼文檔都內置到壓縮包了 https://pan.baidu.com/s/1xwcscTne-JMbmKEntiuAuA?pwd78oi

邏輯分析儀 - 采樣率/采樣深度

采樣深度&#xff08;Sampling Depth&#xff09; 采樣深度指的是邏輯分析儀在一次捕獲過程中可以記錄的最大樣本數量。簡單來說&#xff0c;采樣深度越大&#xff0c;邏輯分析儀可以記錄的數據量就越多。這對于分析長時間的信號變化或復雜的信號序列非常重要。 采樣率&#…

2024年5月23日 (周四) 葉子游戲新聞

《Unclogged》Steam頁面上線 馬桶主題恐怖逃脫解謎Brody制作并發行&#xff0c;一款奇葩創意馬桶主題恐怖逃脫解謎新游《Unclogged》Steam頁面上線&#xff0c;本作暫不支持中文。 Meta人工智能主管楊立昆 大語言模型不會達到人類智能水平IT之家今日&#xff08;5月23日&#x…

QEMU啟動Linux內核

在QEMU環境下啟動linux內核命令如下&#xff1a; QEMU_AUDIO_DRVnone qemu-system-arm -m 256M -nographic -M versatilepb -kernel /home/yukeyang/myfile/linux-6.6.30/arch/arm/boot/zImage -append "consolettyAMA0 rdinit/bin/sh" -dtb arch/arm/boot/dts/arm/…

數據防泄漏系統哪個好用,給文件加密的軟件

數據防泄露&#xff08;Data Leakage Prevention&#xff0c;DLP&#xff09;是指通過一定的技術手段&#xff0c;防止組織指定&#xff08;重要或敏感的&#xff09;數據或信息資產以違反安全策略規定的形式流出組織的一種策略。 信息防泄露以文檔加密技術為核心&#xff0c;…

順序表及其應用

掌握順序表的初始化&#xff0c;初始化、查找、插入、刪除、遍歷、查看實際長度等操作 內容 從鍵盤輸入n個整數&#xff0c;創建順序表。【創建長度為n的順序表】從鍵盤輸入1個整數x&#xff0c;在順序表中查找x所在的位置。若找到&#xff0c;輸出該元素所在的位置(即數組下標…

SQL開窗函數

文章目錄 概念&#xff1a;語法&#xff1a;常用的窗口函數及示例&#xff1a;求平均值&#xff1a;AVG() &#xff1a;求和&#xff1a;SUM():求排名&#xff1a;移動平均計數COUNT():求最大MXA()/小MIN()值求分區內的最大/最小值求當前行的前/后一個值 概念&#xff1a; 開窗…

同旺科技 FLUKE ADPT 隔離版發布 ---- 說明書

所需設備&#xff1a; 1、FLUKE ADPT 隔離版 內附鏈接&#xff1b; 應用于&#xff1a;福祿克Fluke 12E / 15BMax / 17B Max / 101 / 106 / 107 應用于&#xff1a;福祿克Fluke 15B / 17B / 18B

利用文本圖像對比模型進行虛假信息檢測

Harnessing the Power of Text-image Contrastive Models for Automatic Detection of Online Misinformation 論文地址: CVPR 2023 Open Access Repositoryhttps://openaccess.thecvf.com/content/CVPR2023W/WMF/html/Chen_Harnessing_the_Power_of_Text-Image_Contrastive_…

51單片機學習(4)3-1 獨立按鍵控制LED亮滅

#include<REGX52.H> void main() { //P20xFE; P2_01; while(1) { if(P3_10) { P2_00&#xff1b; } else { P2_01&#xff1b; } } }

力扣周賽398題解

特殊數組Ⅰ 如果數組的每一對相鄰元素都是兩個奇偶性不同的數字&#xff0c;則該數組被認為是一個 特殊數組 。 Aging 有一個整數數組 nums。如果 nums 是一個 特殊數組 &#xff0c;返回 true&#xff0c;否則返回 false。 示例 1&#xff1a; 輸入&#xff1a;nums [1] …

SEO:屏蔽流氓蜘蛛抓取

解決屏蔽流氓蜘蛛抓取&#xff0c;如MJ12bot 、DotBot 、BLEXBot 、PetalBot 、DataForSeoBot 1、robots文件屏蔽 User-agent: MJ12bot Disallow: / User-agent:DotBot Disallow: / User-agent:BLEXBot Disallow: / User-agent:PetalBot Disallow: / User-agent:DataForSeoBot…