色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32:SPI總線、W25Q64(FLASH)的詳細(xì)介紹

1126626497 ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2022-03-03 17:06 ? 次閱讀

一、環(huán)境介紹

編程軟件: keil5

操作系統(tǒng): win10

MCU型號: STM32F103ZET6

STM32編程方式: 寄存器開發(fā) (方便程序移植到其他單片機(jī))

SPI總線:STM32本身支持SPI硬件時(shí)序,本文示例代碼里同時(shí)采用模擬時(shí)序和硬件時(shí)序兩種方式讀寫W25Q64。

模擬時(shí)序更加方便移植到其他單片機(jī),更加方便學(xué)習(xí)理解SPI時(shí)序,通用性更高,不分MCU;

硬件時(shí)序效率更高,每個(gè)MCU配置方法不同,依賴MCU硬件本身支持。

存儲(chǔ)器件: 采用華邦W25Q64 flash存儲(chǔ)芯片

W25Q64這類似的Flash存儲(chǔ)芯片在單片機(jī)里、嵌入式系統(tǒng)里還是比較常見,可以用來存儲(chǔ)圖片數(shù)據(jù)、字庫數(shù)據(jù)、音頻數(shù)據(jù)、保存設(shè)備運(yùn)行日志文件等。

二、華邦W25Q64介紹(FLASH存儲(chǔ)類型)

2.1 W25Q64芯片功能介紹

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

W25Q64是為系統(tǒng)提供一個(gè)最小空間、最少引腳,最低功耗的串行Flash存儲(chǔ)器,25Q系列比普通的串行Flash存儲(chǔ)器更靈活,性能更優(yōu)越。

W25Q64支持雙倍/四倍的SPI,可以儲(chǔ)存包括聲音、文本、圖片和其他數(shù)據(jù);芯片支持的工作電壓 2.7V 到 3.6V,正常工作時(shí)電流小于5mA,掉電時(shí)低于1uA,所有芯片提供標(biāo)準(zhǔn)的封裝。

W25Q64的內(nèi)存空間結(jié)構(gòu): 一頁256字節(jié),4K(4096 字節(jié))為一個(gè)扇區(qū),16個(gè)扇區(qū)為1塊,容量為8M字節(jié),共有128個(gè)塊,2048 個(gè)扇區(qū)。

W25Q64每頁大小由256字節(jié)組成,每頁的256字節(jié)用一次頁編程指令即可完成。

擦除指令分別支持: 16頁(1個(gè)扇區(qū))、128頁、256頁、全片擦除。

W25Q64支持標(biāo)準(zhǔn)串行外圍接口(SPI),和高速的雙倍/四倍輸出,雙倍/四倍用的引腳:串行時(shí)鐘、片選端、串行數(shù)據(jù) I/O0(DI)、I/O1(DO)、I/O2(WP)和 I/O3(HOLD)。
SPI 最高支持 80MHz,當(dāng)用快讀雙倍/四倍指令時(shí),相當(dāng)于雙倍輸出時(shí)最高速率160MHz,四倍輸出時(shí)最高速率 320MHz。這個(gè)傳輸速率比得上8位和16位的并行Flash存儲(chǔ)器。

W25Q64支持 JEDEC 標(biāo)準(zhǔn),具有唯一的 64 位識別序列號,方便區(qū)別芯片型號。

2.2 W25Q64芯片特性詳細(xì)介紹

●SPI串行存儲(chǔ)器系列
-W25Q64:64M 位/8M 字節(jié)
-W25Q16:16M 位/2M 字節(jié)
-W25Q32:32M 位/4M 字節(jié)
-每 256 字節(jié)可編程頁


●靈活的4KB扇區(qū)結(jié)構(gòu)
-統(tǒng)一的扇區(qū)擦除(4K 字節(jié))
-塊擦除(32K 和 64K 字節(jié))
-一次編程 256 字節(jié)
-至少 100,000 寫/擦除周期
-數(shù)據(jù)保存 20 年

●標(biāo)準(zhǔn)、雙倍和四倍SPI
-標(biāo)準(zhǔn) SPI:CLK、CS、DI、DO、WP、HOLD
-雙倍 SPI:CLK、CS、IO0、IO1、WP、HOLD
-四倍 SPI:CLK、CS、IO0、IO1、IO2、IO3

●高級的安全特點(diǎn)
-軟件和硬件寫保護(hù)
-選擇扇區(qū)和塊保護(hù)
-一次性編程保護(hù)(1)
-每個(gè)設(shè)備具有唯一的64位ID(1)

●高性能串行Flash存儲(chǔ)器
-比普通串行Flash性能高6倍
-80MHz時(shí)鐘頻率
-雙倍SPI相當(dāng)于160MHz
-四倍SPI相當(dāng)于320MHz
-40MB/S連續(xù)傳輸數(shù)據(jù)
-30MB/S隨機(jī)存取(每32字節(jié))
-比得上16位并行存儲(chǔ)器

●低功耗、寬溫度范圍
-單電源 2.7V-3.6V
-工作電流 4mA,掉電<1μA(典型值)
-40℃~+85℃工作

2.3 引腳介紹

下面只介紹W25Q64標(biāo)準(zhǔn)SPI接口,因?yàn)槟壳伴_發(fā)板上的封裝使用的就是標(biāo)準(zhǔn)SPI接口。

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

引腳編號

引腳名稱

I/O

功能

1

/CS

I

片選端輸入

2

DO(IO1)

I/O

數(shù)據(jù)輸出(數(shù)據(jù)輸入輸出 1)*1

3

/WP(IO2)

I/O

寫保護(hù)輸入(數(shù)據(jù)輸入輸出 2)*2

4

GND

5

DI(IO0)

I/O

數(shù)據(jù)輸入(數(shù)據(jù)輸入輸出 0)*1

6

CLK

I

串行時(shí)鐘輸入

7

/HOLD(IO3)

I/O

保持端輸入(數(shù)據(jù)輸入輸出 3)*2

8

VCC

電源

2.2.1 SPI片選(/CS)引腳用于使能和禁止芯片操作

CS引腳是W25Q64的片選引腳,用于選中芯片;當(dāng)CS為高電平時(shí),芯片未被選擇,串行數(shù)據(jù)輸出(DO、IO0、IO1、IO2 和 IO3)引腳為高阻態(tài)。未被選擇時(shí),芯片處于待機(jī)狀態(tài)下的低功耗,除非芯片內(nèi)部在擦除、編程。當(dāng)/CS 變成低電平,芯片功耗將增長到正常工作,能夠從芯片讀寫數(shù)據(jù)。上電后, 在接收新的指令前,/CS 必須由高變?yōu)榈碗娖健I想姾螅?CS 必須上升到 VCC,在/CS 接上拉電阻可以完成這個(gè)操作。

2.2.2 串行數(shù)據(jù)輸入、輸出和 IOs(DI、DO 和 IO0、IO1、IO2、IO3)

W25Q64、W25Q16 和 W25Q32 支持標(biāo)準(zhǔn) SPI、雙倍 SPI 和四倍 SPI。

標(biāo)準(zhǔn)的 SPI 傳輸用單向的 DI(輸入)引腳連續(xù)的寫命令、地址或者數(shù)據(jù)在串行時(shí)鐘(CLK)的上升沿時(shí)寫入到芯片內(nèi)。

標(biāo)準(zhǔn)的SPI 用單向的 DO(輸出)在 CLK 的下降沿從芯片內(nèi)讀出數(shù)據(jù)或狀態(tài)。

2.2.3 寫保護(hù)(/WP)

寫保護(hù)引腳(/WP)用來保護(hù)狀態(tài)寄存器。和狀態(tài)寄存器的塊保護(hù)位(SEC、TB、BP2、BP1 和BP0)和狀態(tài)寄存器保護(hù)位(SRP)對存儲(chǔ)器進(jìn)行一部分或者全部的硬件保護(hù)。/WP 引腳低電平有效。當(dāng)狀態(tài)寄存器 2 的 QE 位被置位了,/WP 引腳(硬件寫保護(hù))的功能不可用。

2.2.4 保持端(/HOLD)

當(dāng)/HOLD 引腳是有效時(shí),允許芯片暫停工作。在/CS 為低電平時(shí),當(dāng)/HOLD 變?yōu)榈碗娖剑珼O 引腳將變?yōu)楦咦钁B(tài),在 DI 和 CLK 引腳上的信號將無效。當(dāng)/HOLD 變?yōu)楦唠娖剑酒謴?fù)工作。/HOLD 功能用在當(dāng)有多個(gè)設(shè)備共享同一 SPI 總線時(shí)。/HOLD 引腳低電平有效。當(dāng)狀態(tài)寄存器 2 的 QE 位被置位了,/ HOLD 引腳的功能不可用。

2.2.5 串行時(shí)鐘(CLK)

串行時(shí)鐘輸入引腳為串行輸入和輸出操作提供時(shí)序。(見 SPI 操作)。

設(shè)備數(shù)據(jù)傳輸是從高位開始,數(shù)據(jù)傳輸?shù)母袷綖?8bit,數(shù)據(jù)采樣從第二個(gè)時(shí)間邊沿開始,空閑狀態(tài)時(shí),時(shí)鐘線 clk 為高電平。

2.3 內(nèi)部結(jié)構(gòu)框架圖

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

2.4 W25Q64的標(biāo)準(zhǔn)SPI操作流程

W25Q64標(biāo)準(zhǔn)SPI總線接口包含四個(gè)信號: 串行時(shí)鐘(CLK)、片選端(/CS)、串行數(shù)據(jù)輸入(DI)和串行數(shù)據(jù)輸出(DO)

DI輸入引腳在CLK的上升沿連續(xù)寫命令、地址或數(shù)據(jù)到芯片內(nèi)。

DO輸出引腳在CLK的下降沿從芯片內(nèi)讀出數(shù)據(jù)或狀態(tài)。

W25Q64分別支持SPI總線工作模式0和工作模式3。模式0和模式3的主要區(qū)別在于常態(tài)時(shí)的CLK信號不同;對于模式0來說,當(dāng)SPI主機(jī)已準(zhǔn)備好數(shù)據(jù)還沒傳輸?shù)酱蠪lash中時(shí),CLK信號常態(tài)為低;

設(shè)備數(shù)據(jù)傳輸是從高位開始,數(shù)據(jù)傳輸?shù)母袷綖?bit,數(shù)據(jù)采樣從第二個(gè)時(shí)間邊沿開始,空閑狀態(tài)時(shí),時(shí)鐘線clk為高電平

2.5 部分控制和狀態(tài)寄存器介紹

2.5.1 W25Q64的指令表

指令名稱

字節(jié) 1

(代碼)

字節(jié) 2

字節(jié) 3

字節(jié) 4

字節(jié) 5

字節(jié) 6

寫使能

06h

write_enabled

禁止寫

04h

讀狀態(tài)寄存器 1

05h

(S7-S0)(2)

讀狀態(tài)寄存器 2

35h

(S15-S8)(2)

寫狀態(tài)寄存器

01h

(S7-S0)

(S15-S8)

頁編程

02h

A23-A16

A15-A8

A7-A0

(D7-D0)

四倍頁編程

32h

A23-A16

A15-A8

A7-A0

(D7-D0,…)(3)

塊擦除(64KB)

D8h

A23-A16

A15-A8

A7-A0

塊擦除(32KB)

52h

A23-A16

A15-A8

A7-A0

扇區(qū)擦除(4KB)

20h

A23-A16

A15-A8

A7-A0

全片擦除

C7h/60h

暫停擦除

75h

恢復(fù)擦除

7Ah

掉電模式

B9h

高性能模式

A3h

2.5.2 讀狀態(tài)寄存器1

狀態(tài)寄存器1的內(nèi)部結(jié)構(gòu)如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

狀態(tài)寄存器1的S0位是當(dāng)前W25Q64的忙狀態(tài);為1的時(shí)候表示設(shè)備正在執(zhí)行程序(可能是在擦除芯片)或?qū)憼顟B(tài)寄存器指令,這個(gè)時(shí)候設(shè)備將忽略傳來的指令, 除了讀狀態(tài)寄存器和擦除暫停指令外,其他寫指令或?qū)憼顟B(tài)指令都無效, 當(dāng) S0 為 0 狀態(tài)時(shí)指示設(shè)備已經(jīng)執(zhí)行完畢,可以進(jìn)行下一步操作。

讀狀態(tài)寄存器1的時(shí)序如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取狀態(tài)寄存器的指令是 8 位的指令。發(fā)送指令之前,先將/CS 拉低,再發(fā)送指令碼“05 h” 或者“35h”。設(shè)備收到讀取狀態(tài)寄存器的指令后,將狀態(tài)信息(高位)依次移位發(fā)送出去,讀出的狀態(tài)信息,最低位為 1 代表忙,最低位為 0 代表可以操作,狀態(tài)信息讀取完畢,將片選線拉高。

讀狀態(tài)寄存器指令可以使用在任何時(shí)候,即使程序在擦除的過程中或者寫狀態(tài)寄存器周期正在進(jìn)行中。這可以檢測忙碌狀態(tài)來確定周期是否完成,以確定設(shè)備是否可以接受另一個(gè)指令。

2.5.3 讀制造商ID和芯片ID

時(shí)序圖如下:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取制造商/設(shè)備 ID 指令可以讀取制造商 ID 和特定的設(shè)備 ID。讀取之前,拉低 CS 片選信號,接著發(fā)送指令代碼“90h” ,緊隨其后的是一個(gè) 24 位地址(A23-A0)000000h。 設(shè)備收到指令之后,會(huì)發(fā)出華邦電子制造商 ID(EFh) 和設(shè)備ID(w25q64 為 16h)。如果 24 位地址設(shè)置為 000001h ,設(shè)備 ID 會(huì)先發(fā)出,然后跟著制造商 ID。制造商和設(shè)備ID可以連續(xù)讀取。完成指令后,片選信號/ CS 拉高。

2.5.4 全片擦除(C7h/60h)

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

全芯片擦除指令,可以將整個(gè)芯片的所有內(nèi)存數(shù)據(jù)擦除,恢復(fù)到 0XFF 狀態(tài)。寫入全芯片擦除指令之前必須執(zhí)行設(shè)備寫使能(發(fā)送設(shè)備寫使能指令 0x06),并判斷狀態(tài)寄存器(狀態(tài)寄存器位最低位必須等于 0 才能操作)。發(fā)送全芯片擦除指令前,先拉低/ CS,接著發(fā)送擦除指令碼”C7h”或者是”60h”, 指令碼發(fā)送完畢后,拉高片選線 CS/,,并判斷狀態(tài)位,等待擦除結(jié)束。全片擦除指令盡量少用,擦除會(huì)縮短設(shè)備的壽命。

2.5.5 讀數(shù)據(jù)(03h)

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

讀取數(shù)據(jù)指令允許按順序讀取一個(gè)字節(jié)的內(nèi)存數(shù)據(jù)。當(dāng)片選 CS/拉低之后,緊隨其后是一個(gè) 24 位的地址(A23-A0)(需要發(fā)送 3 次,每次 8 個(gè)字節(jié),先發(fā)高位)。芯片收到地址后,將要讀的數(shù)據(jù)按字節(jié)大小轉(zhuǎn)移出去,數(shù)據(jù)是先轉(zhuǎn)移高位,對于單片機(jī),時(shí)鐘下降沿發(fā)送數(shù)據(jù),上升沿接收數(shù)據(jù)。讀數(shù)據(jù)時(shí),地址會(huì)自動(dòng)增加,允許連續(xù)的讀取數(shù)據(jù)。這意味著讀取整個(gè)內(nèi)存的數(shù)據(jù),只要用一個(gè)指令就可以讀完。數(shù)據(jù)讀取完成之后,片選信號/ CS 拉高。

讀取數(shù)據(jù)的指令序列,如上圖所示。如果一個(gè)讀數(shù)據(jù)指令而發(fā)出的時(shí)候,設(shè)備正在擦除扇區(qū),或者(忙= 1),該讀指令將被忽略,也不會(huì)對當(dāng)前周期有什么影響。

三、SPI時(shí)序介紹

SPI是串行外設(shè)接口(Serial Peripheral Interface)的縮寫,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時(shí)為PCB的布局上節(jié)省空間。

SPI是一種高速、高效率的串行接口技術(shù),一共有4根線。通常由一個(gè)主模塊和一個(gè)或多個(gè)從模塊組成,主模塊選擇一個(gè)從模塊進(jìn)行同步通信,從而完成數(shù)據(jù)的交換。SPI是一個(gè)環(huán)形結(jié)構(gòu),通信時(shí)需要至少4根線(在單向傳輸時(shí)3根線也可以)。分別是MISO(主設(shè)備數(shù)據(jù)輸入)、MOSI(主設(shè)備數(shù)據(jù)輸出)、SCLK(時(shí)鐘)、CS(片選)。
(1)MISO– Master Input Slave Output,主設(shè)備數(shù)據(jù)輸入,從設(shè)備數(shù)據(jù)輸出;
(2)MOSI– Master Output Slave Input,主設(shè)備數(shù)據(jù)輸出,從設(shè)備數(shù)據(jù)輸入;
(3)SCLK – Serial Clock,時(shí)鐘信號,由主設(shè)備產(chǎn)生;
(4)CS – Chip Select,從設(shè)備使能信號,由主設(shè)備控制。

其中,CS是從芯片是否被主芯片選中的控制信號,也就是說只有片選信號為預(yù)先規(guī)定的使能信號時(shí)(高電位或低電位),主芯片對此從芯片的操作才有效。這就使在同一條總線上連接多個(gè)SPI設(shè)備成為可能。接下來就負(fù)責(zé)通訊的3根線了。通訊是通過數(shù)據(jù)交換完成的,這里先要知道SPI是串行通訊協(xié)議,也就是說數(shù)據(jù)是一位一位的傳輸?shù)摹_@就是SCLK時(shí)鐘線存在的原因,由SCLK提供時(shí)鐘脈沖,SDISDO則基于此脈沖完成數(shù)據(jù)傳輸。數(shù)據(jù)輸出通過 SDO線,數(shù)據(jù)在時(shí)鐘上升沿或下降沿時(shí)改變,在緊接著的下降沿或上升沿被讀取。完成一位數(shù)據(jù)傳輸,輸入也使用同樣原理。因此,至少需要8次時(shí)鐘信號的改變(上沿和下沿為一次),才能完成8位數(shù)據(jù)的傳輸。
時(shí)鐘信號線SCLK只能由主設(shè)備控制,從設(shè)備不能控制。這樣的傳輸方式有一個(gè)優(yōu)點(diǎn),在數(shù)據(jù)位的傳輸過程中可以暫停,也就是時(shí)鐘的周期可以為不等寬,因?yàn)闀r(shí)鐘線由主設(shè)備控制,當(dāng)沒有時(shí)鐘跳變時(shí),從設(shè)備不采集或傳送數(shù)據(jù)。SPI還是一個(gè)數(shù)據(jù)交換協(xié)議:因?yàn)镾PI的數(shù)據(jù)輸入和輸出線獨(dú)立,所以允許同時(shí)完成數(shù)據(jù)的輸入和輸出。芯片集成的SPI串行同步時(shí)鐘極性和相位可以通過寄存器配置,IO模擬的SPI串行同步時(shí)鐘需要根據(jù)從設(shè)備支持的時(shí)鐘極性和相位來通訊。SPI通信原理比I2C要簡單,IIC有應(yīng)答機(jī)制,可以確保數(shù)據(jù)都全部發(fā)送成。SPI接口沒有指定的流控制,沒有應(yīng)答機(jī)制確認(rèn)是否接收到數(shù)據(jù),速度上更加快。

SPI總線通過時(shí)鐘極性和相位可以配置成4種時(shí)序:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

STM32F103參考手冊,SPI章節(jié)介紹的時(shí)序圖:

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

SPI時(shí)序比較簡單,CPU如果沒有硬件支持,可以直接寫代碼采用IO口模擬,下面是模擬時(shí)序的示例的代碼:

完整工程代碼下載:https://download.csdn.net/download/xiaolong1126626497/19425042

SPI的模式1:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=0; //空閑電平(默認(rèn)初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機(jī)發(fā)送一位數(shù)據(jù)*/
		SCK=0;//告訴從機(jī),主機(jī)將要發(fā)送數(shù)據(jù)
		if(tx_data&0x80)MOSI=1; //發(fā)送數(shù)據(jù)
		else MOSI=0;
		SCK=1; //告訴從機(jī),主機(jī)數(shù)據(jù)發(fā)送完畢
		tx_data<<=1; //繼續(xù)發(fā)送下一位
		
		/*2. 主機(jī)接收一位數(shù)據(jù)*/
		rx_data<<=1; //默認(rèn)認(rèn)為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=0; //恢復(fù)空閑電平
	return rx_data;
}

SPI的模式2:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=0; //空閑電平(默認(rèn)初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機(jī)發(fā)送一位數(shù)據(jù)*/
		SCK=1;//告訴從機(jī),主機(jī)將要發(fā)送數(shù)據(jù)
		if(tx_data&0x80)MOSI=1; //發(fā)送數(shù)據(jù)
		else MOSI=0;
		SCK=0; //告訴從機(jī),主機(jī)數(shù)據(jù)發(fā)送完畢
		tx_data<<=1; //繼續(xù)發(fā)送下一位
		
		/*2. 主機(jī)接收一位數(shù)據(jù)*/
		rx_data<<=1; //默認(rèn)認(rèn)為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=0; //恢復(fù)空閑電平
	return rx_data;
}


SPI的模式3:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=1; //空閑電平(默認(rèn)初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機(jī)發(fā)送一位數(shù)據(jù)*/
		SCK=1;//告訴從機(jī),主機(jī)將要發(fā)送數(shù)據(jù)
		if(tx_data&0x80)MOSI=1; //發(fā)送數(shù)據(jù)
		else MOSI=0;
		SCK=0; //告訴從機(jī),主機(jī)數(shù)據(jù)發(fā)送完畢
		tx_data<<=1; //繼續(xù)發(fā)送下一位
		
		/*2. 主機(jī)接收一位數(shù)據(jù)*/
		rx_data<<=1; //默認(rèn)認(rèn)為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=1; //恢復(fù)空閑電平
	return rx_data;
}

SPI的模式4:
u8 SPI_ReadWriteOneByte(u8 tx_data)
{
	u8 i,rx_data=0;
	SCK=1; //空閑電平(默認(rèn)初始化情況)
	for(i=0;i<8;i++)
	{
		/*1. 主機(jī)發(fā)送一位數(shù)據(jù)*/
		SCK=0;//告訴從機(jī),主機(jī)將要發(fā)送數(shù)據(jù)
		if(tx_data&0x80)MOSI=1; //發(fā)送數(shù)據(jù)
		else MOSI=0;
		SCK=1; //告訴從機(jī),主機(jī)數(shù)據(jù)發(fā)送完畢
		tx_data<<=1; //繼續(xù)發(fā)送下一位
		
		/*2. 主機(jī)接收一位數(shù)據(jù)*/
		rx_data<<=1; //默認(rèn)認(rèn)為接收到0
		if(MISO)rx_data|=0x01;
	}
	SCK=1; //恢復(fù)空閑電平
	return rx_data;
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

四、W25Q64的示例代碼

4.1 STM32采用硬件SPI讀寫W25Q64示例代碼

/*
函數(shù)功能:SPI初始化(模擬SPI)
硬件連接:
MISO--->PB14
MOSI--->PB15
SCLK--->PB13
*/
void SPI_Init(void)
{
	/*開啟時(shí)鐘*/
	RCC->APB1ENR|=1<<14;   //開啟SPI2時(shí)鐘
	RCC->APB2ENR|=1<<3;    //PB
	GPIOB->CRH&=0X000FFFFF; //清除寄存器
	GPIOB->CRH|=0XB8B00000;
	GPIOB->ODR|=0X7<<13;    	//PB13/14/15上拉--輸出高電平
	/*SPI2基本配置*/
	SPI2->CR1=0X0; 		//清空寄存器
	SPI2->CR1|=0<<15; //選擇“雙線雙向”模式
	SPI2->CR1|=0<<11; //使用8位數(shù)據(jù)幀格式進(jìn)行發(fā)送/接收;
	SPI2->CR1|=0<<10; //全雙工(發(fā)送和接收);
	SPI2->CR1|=1<<9;  //啟用軟件從設(shè)備管理
	SPI2->CR1|=1<<8;  //NSS
	SPI2->CR1|=0<<7;  //幀格式,先發(fā)送高位
	SPI2->CR1|=0x0<<3;//當(dāng)總線頻率為36MHZ時(shí),SPI速度為18MHZ,高速。
	SPI2->CR1|=1<<2;  //配置為主設(shè)備
	SPI2->CR1|=1<<1;  //空閑狀態(tài)時(shí), SCK保持高電平。
	SPI2->CR1|=1<<0;  //數(shù)據(jù)采樣從第二個(gè)時(shí)鐘邊沿開始。
	SPI2->CR1|=1<<6;  //開啟SPI設(shè)備。
}


/*
函數(shù)功能:SPI讀寫一個(gè)字節(jié)
*/
u8 SPI_ReadWriteOneByte(u8 data_tx)
{
    u16 cnt=0;				 
    while((SPI2->SR&1<<1)==0)		 //等待發(fā)送區(qū)空--等待發(fā)送緩沖為空	
    {
      cnt++;
      if(cnt>=65530)return 0; 	  //超時(shí)退出  u16=2個(gè)字節(jié)
    }	
    SPI2->DR=data_tx;	 	  		      //發(fā)送一個(gè)byte 
    cnt=0;
    while((SPI2->SR&1<<0)==0) 		//等待接收完一個(gè)byte   
    {
      cnt++;
      if(cnt>=65530)return 0;	   //超時(shí)退出
    }	  						    
    return SPI2->DR;          		//返回收到的數(shù)據(jù)	
}


/*
函數(shù)功能:W25Q64初始化
硬件連接:
MOSI--->PB15
MISO--->PB14
SCLK--->PB13
CS----->PB12
*/
void W25Q64_Init(void)
{
	/*1. 開時(shí)鐘*/
	RCC->APB2ENR|=1<<3; //PB
	
	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0xFFF0FFFF;
	GPIOB->CRH|=0x00030000;
	
	W25Q64_CS=1; //未選中芯片
	SPI_Init();   //SPI初始化
}


/*
函數(shù)功能:讀取芯片的ID號
*/
u16 W25Q64_ReadID(void)
{
	u16 id;
	/*1. 拉低片選*/
	W25Q64_CS=0;
	
	/*2. 發(fā)送讀取ID的指令*/
	SPI_ReadWriteOneByte(0x90);
	
	/*3. 發(fā)送24位的地址-0*/
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	
	/*4. 讀取芯片的ID*/
	id=SPI_ReadWriteOneByte(0xFF)<<8;
	id|=SPI_ReadWriteOneByte(0xFF);

	/*5. 拉高片選*/
	W25Q64_CS=1;
	return id;
}

/*
函數(shù)功能:檢測W25Q64狀態(tài)
*/
void W25Q64_CheckStat(void)
{
	u8 stat=1;
	while(stat&1<<0)
	{
		W25Q64_CS=0; //選中芯片
		SPI_ReadWriteOneByte(0x05);      //發(fā)送讀狀態(tài)寄存器1指令
		stat=SPI_ReadWriteOneByte(0xFF); //讀取狀態(tài)
		W25Q64_CS=1; //取消選中芯片
	}
}


/*
函數(shù)功能:頁編程
說    明:一頁最多寫256個(gè)字節(jié)。 寫數(shù)據(jù)之前,必須保證空間是0xFF
函數(shù)參數(shù):
u32 addr:頁編程起始地址
u8 *buff:寫入的數(shù)據(jù)緩沖區(qū)
u16 len :寫入的字節(jié)長度
*/
void W25Q64_PageWrite(u32 addr,u8 *buff,u16 len)
{
	u16 i;
	W25Q64_Enabled();  						//寫使能
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x02); //頁編程指令
	SPI_ReadWriteOneByte(addr>>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址

	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	W25Q64_CS=1; 				//取消選中芯片
	W25Q64_CheckStat();  //檢測芯片忙狀態(tài)
}

/*
函數(shù)功能:寫使能
*/
void W25Q64_Enabled(void)
{
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x06);     //寫使能
	W25Q64_CS=1; //取消選中芯片
}


/*
函數(shù)功能:指定位置寫入指定個(gè)數(shù)的數(shù)據(jù),不考慮擦除問題
注意事項(xiàng):W25Q64只能將1寫為,不能將0寫為1。
函數(shù)參數(shù):
u32 addr---寫入數(shù)據(jù)的起始地址
u8 *buff---寫入的數(shù)據(jù)
u32 len---長度
*/
void W25Q64_WriteByteDataNoCheck(u32 addr,u8 *buff,u32 len)
{
	u32 page_remain=256-addr%256; //計(jì)算當(dāng)前頁還可以寫下多少數(shù)據(jù)
	if(len<=page_remain) //如果當(dāng)前寫入的字節(jié)長度小于剩余的長度
	{
		page_remain=len;
	}
	while(1)
	{
		W25Q64_PageWrite(addr,buff,page_remain);
		if(page_remain==len)break; //表明數(shù)據(jù)已經(jīng)寫入完畢
		buff+=page_remain; //buff向后偏移地址
		addr+=page_remain; //起始地址向后偏移
		len-=page_remain;  //減去已經(jīng)寫入的字節(jié)數(shù)
		if(len>256)page_remain=256;  //如果大于一頁,每次就直接寫256字節(jié)
		else page_remain=len;
	}
}


/*
函數(shù)功能:指定位置寫入指定個(gè)數(shù)的數(shù)據(jù),考慮擦除問題,完善代碼
函數(shù)參數(shù):
u32 addr---寫入數(shù)據(jù)的起始地址
u8 *buff---寫入的數(shù)據(jù)
u32 len---長度
說明:擦除的最小單位扇區(qū),4096字節(jié)
*/
static u8 W25Q64_READ_WRITE_CHECK_BUFF[4096];
void W25Q64_WriteByteData(u32 addr,u8 *buff,u32 len)
{
    u32 i;
    u32 len_w;
    u32 sector_addr; //存放扇區(qū)的地址
    u32 sector_move; //扇區(qū)向后偏移的地址
    u32 sector_size; //扇區(qū)大小。(剩余的空間大小)
    u8 *p=W25Q64_READ_WRITE_CHECK_BUFF;//存放指針
    sector_addr=addr/4096; //傳入的地址是處于第幾個(gè)扇區(qū)
    sector_move=addr%4096; //計(jì)算傳入的地址存于當(dāng)前的扇區(qū)的偏移量位置
    sector_size=4096-sector_move; //得到當(dāng)前扇區(qū)剩余的空間

    if(len<=sector_size)
    {
            sector_size=len; //判斷第一種可能性、一次可以寫完
    }
    
    while(1)
    {
        W25Q64_ReadByteData(addr,p,sector_size);	 //讀取剩余扇區(qū)里的數(shù)據(jù)
        for(i=0;i4096)       //表明還可以寫一個(gè)扇區(qū)
        {
                sector_size=4096;//繼續(xù)寫一個(gè)扇區(qū)
        }
        else
        {
                sector_size=len; //剩余的空間可以寫完
        }
    }
}
;i++)>;i++)buff[i]=spi_readwriteonebyte(0xff);>;i++)>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

4.2STM32采用硬件SPI讀寫W25Q64示例代碼

#include "spi.h"


/*
函數(shù)功能:SPI初始化(模擬SPI)
硬件連接:
MISO--->PB14
MOSI--->PB15
SCLK--->PB13
*/
void SPI_Init(void)
{
	/*1. 開時(shí)鐘*/
	RCC->APB2ENR|=1<<3; //PB

	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0x000FFFFF;
	GPIOB->CRH|=0x38300000;

	/*3. 上拉*/
	SPI_MOSI=1;
	SPI_MISO=1;
	SPI_SCLK=1;
}

/*
函數(shù)功能:SPI讀寫一個(gè)字節(jié)
*/
u8 SPI_ReadWriteOneByte(u8 data_tx)
{
	u8 data_rx=0; //存放讀取的數(shù)據(jù)
	u8 i;
	for(i=0;i<8;i++)
	{
		SPI_SCLK=0; //準(zhǔn)備發(fā)送數(shù)據(jù)
		if(data_tx&0x80)SPI_MOSI=1;
		else SPI_MOSI=0;
		data_tx<<=1; //依次發(fā)送最高位
		SPI_SCLK=1;  //表示主機(jī)數(shù)據(jù)發(fā)送完成,表示從機(jī)發(fā)送完畢
		
		data_rx<<=1; //表示默認(rèn)接收的是0
		if(SPI_MISO)data_rx|=0x01;
	}
	return data_rx;
}

#include "W25Q64.h"

/*
函數(shù)功能:W25Q64初始化
硬件連接:
MOSI--->PB15
MISO--->PB14
SCLK--->PB13
CS----->PB12
*/
void W25Q64_Init(void)
{
	/*1. 開時(shí)鐘*/
	RCC->APB2ENR|=1<<3; //PB
	
	/*2. 配置GPIO口模式*/
	GPIOB->CRH&=0xFFF0FFFF;
	GPIOB->CRH|=0x00030000;
	
	W25Q64_CS=1; //未選中芯片
	SPI_Init();   //SPI初始化
}


/*
函數(shù)功能:讀取芯片的ID號
*/
u16 W25Q64_ReadID(void)
{
	u16 id;
	/*1. 拉低片選*/
	W25Q64_CS=0;

	/*2. 發(fā)送讀取ID的指令*/
	SPI_ReadWriteOneByte(0x90);

	/*3. 發(fā)送24位的地址-0*/
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);
	SPI_ReadWriteOneByte(0);

	/*4. 讀取芯片的ID*/
	id=SPI_ReadWriteOneByte(0xFF)<<8;
	id|=SPI_ReadWriteOneByte(0xFF);

	/*5. 拉高片選*/
	W25Q64_CS=1;
	return id;
}

/*
函數(shù)功能:檢測W25Q64狀態(tài)
*/
void W25Q64_CheckStat(void)
{
	u8 stat=1;
	while(stat&1<<0)
	{
		W25Q64_CS=0; //選中芯片
		SPI_ReadWriteOneByte(0x05);      //發(fā)送讀狀態(tài)寄存器1指令
		stat=SPI_ReadWriteOneByte(0xFF); //讀取狀態(tài)
		W25Q64_CS=1; //取消選中芯片
	}
}


/*
函數(shù)功能:頁編程
說    明:一頁最多寫256個(gè)字節(jié)。 寫數(shù)據(jù)之前,必須保證空間是0xFF
函數(shù)參數(shù):
u32 addr:頁編程起始地址
u8 *buff:寫入的數(shù)據(jù)緩沖區(qū)
u16 len :寫入的字節(jié)長度
*/
void W25Q64_PageWrite(u32 addr,u8 *buff,u16 len)
{
	u16 i;
	W25Q64_Enabled();  						//寫使能
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x02); //頁編程指令
	SPI_ReadWriteOneByte(addr>>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址

	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	for(i=0;i>16); //24~16地址
	SPI_ReadWriteOneByte(addr>>8);  //16~8地址
	SPI_ReadWriteOneByte(addr);     //8~0地址
	W25Q64_CS=1; 				//取消選中芯片
	W25Q64_CheckStat();  //檢測芯片忙狀態(tài)
}

/*
函數(shù)功能:寫使能
*/
void W25Q64_Enabled(void)
{
	W25Q64_CS=0; //選中芯片
	SPI_ReadWriteOneByte(0x06);     //寫使能
	W25Q64_CS=1; //取消選中芯片
}


/*
函數(shù)功能:指定位置寫入指定個(gè)數(shù)的數(shù)據(jù),不考慮擦除問題
注意事項(xiàng):W25Q64只能將1寫為,不能將0寫為1。
函數(shù)參數(shù):
u32 addr---寫入數(shù)據(jù)的起始地址
u8 *buff---寫入的數(shù)據(jù)
u32 len---長度
*/
void W25Q64_WriteByteDataNoCheck(u32 addr,u8 *buff,u32 len)
{
	u32 page_remain=256-addr%256; //計(jì)算當(dāng)前頁還可以寫下多少數(shù)據(jù)
	if(len<=page_remain) //如果當(dāng)前寫入的字節(jié)長度小于剩余的長度
	{
		page_remain=len;
	}
	while(1)
	{
		W25Q64_PageWrite(addr,buff,page_remain);
		if(page_remain==len)break; //表明數(shù)據(jù)已經(jīng)寫入完畢
		buff+=page_remain; //buff向后偏移地址
		addr+=page_remain; //起始地址向后偏移
		len-=page_remain;  //減去已經(jīng)寫入的字節(jié)數(shù)
		if(len>256)page_remain=256;  //如果大于一頁,每次就直接寫256字節(jié)
		else page_remain=len;
	}
}


/*
函數(shù)功能:指定位置寫入指定個(gè)數(shù)的數(shù)據(jù),考慮擦除問題,完善代碼
函數(shù)參數(shù):
u32 addr---寫入數(shù)據(jù)的起始地址
u8 *buff---寫入的數(shù)據(jù)
u32 len---長度
說明:擦除的最小單位扇區(qū),4096字節(jié)
*/
static u8 W25Q64_READ_WRITE_CHECK_BUFF[4096];
void W25Q64_WriteByteData(u32 addr,u8 *buff,u32 len)
{
	u32 i;
	u32 sector_addr; //存放扇區(qū)的地址
	u32 sector_move; //扇區(qū)向后偏移的地址
	u32 sector_size; //扇區(qū)大小。(剩余的空間大小)
	u8 *p=W25Q64_READ_WRITE_CHECK_BUFF;//存放指針
	sector_addr=addr/4096; //傳入的地址是處于第幾個(gè)扇區(qū)
	sector_move=addr%4096; //計(jì)算傳入的地址存于當(dāng)前的扇區(qū)的偏移量位置
	sector_size=4096-sector_move; //得到當(dāng)前扇區(qū)剩余的空間

	if(len<=sector_size)
	{
		sector_size=len; //判斷第一種可能性、一次可以寫完
	}

	while(1)
	{
		W25Q64_ReadByteData(addr,p,sector_size);	 //讀取剩余扇區(qū)里的數(shù)據(jù)
		for(i=0;i4096)       //表明還可以寫一個(gè)扇區(qū)
		{
			sector_size=4096;//繼續(xù)寫一個(gè)扇區(qū)
		}
		else
		{
			sector_size=len; //剩余的空間可以寫完
		}
	}
}
;i++)>;i++)buff[i]=spi_readwriteonebyte(0xff);>;i++)>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png審核編輯:符乾江
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10896

    瀏覽量

    355787
  • SPI總線
    +關(guān)注

    關(guān)注

    4

    文章

    103

    瀏覽量

    27586
收藏 人收藏

    評論

    相關(guān)推薦

    W25Q64串行FLASH基礎(chǔ)知識大小

    Flash芯片內(nèi)的數(shù)據(jù)只能由1變0,不能由0變1。W25Q64Flash工作方式:1)W25Q64 SPI數(shù)據(jù)傳輸時(shí)序 W25Q64支持
    發(fā)表于 07-22 09:32

    W25Q64是什么?怎樣去使用W25Q64

    W25Q64是什么?怎樣去使用W25Q64呢?Flash與EEPROM的區(qū)別有哪些呢?
    發(fā)表于 12-20 06:32

    介紹W25Q64和驅(qū)動(dòng)函數(shù)

    可說的。關(guān)于FATFS的移植下一篇文章介紹。本篇文章主要介紹W25Q64和驅(qū)動(dòng)函數(shù)。W25Q64容量是64Mbit的
    發(fā)表于 01-26 07:53

    【技術(shù)精選】嵌入式STM32原創(chuàng)征文活動(dòng)精選文章

    總線W25Q64FLASH)的詳細(xì)介紹STM32: 介紹
    發(fā)表于 07-27 18:26

    w25Q64中文手冊

    w25Q64中文手冊
    發(fā)表于 10-16 15:25 ?714次下載
    <b class='flag-5'>w25Q64</b>中文手冊

    w25Q64的中文手冊

    w25Q64的中文手冊
    發(fā)表于 10-19 08:59 ?338次下載
    <b class='flag-5'>w25Q64</b>的中文手冊

    STM32Cube-18】使用硬件QSPI讀寫SPI FlashW25Q64

    本篇詳細(xì)的記錄了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外設(shè)與 SPI Flash 通信(
    發(fā)表于 12-01 21:06 ?14次下載
    【<b class='flag-5'>STM32</b>Cube-18】使用硬件QSPI讀寫<b class='flag-5'>SPI</b> <b class='flag-5'>Flash</b>(<b class='flag-5'>W25Q64</b>)

    STM32入門開發(fā): 介紹SPI總線、讀寫W25Q64(FLASH)(硬件+模擬時(shí)序)

    時(shí)序,本文示例代碼里同時(shí)采用模擬時(shí)序和硬件時(shí)序兩種方式讀寫W25Q64。模擬時(shí)序更加方便移植到其他單片機(jī),更加方便學(xué)習(xí)理解SPI時(shí)序,通用性更高,不分MCU;硬件時(shí)序效率更高,每個(gè)MCU配置方法不同,依賴MCU硬件本身支持。存儲(chǔ)器件: 采用華邦
    發(fā)表于 12-02 09:06 ?41次下載
    <b class='flag-5'>STM32</b>入門開發(fā): <b class='flag-5'>介紹</b><b class='flag-5'>SPI</b><b class='flag-5'>總線</b>、讀寫<b class='flag-5'>W25Q64</b>(<b class='flag-5'>FLASH</b>)(硬件+模擬時(shí)序)

    STM32單片機(jī)基礎(chǔ)18——使用硬件QSPI讀寫SPI FlashW25Q64

    本篇詳細(xì)的記錄了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外設(shè)與 SPI Flash 通信(
    發(fā)表于 12-02 10:21 ?19次下載
    <b class='flag-5'>STM32</b>單片機(jī)基礎(chǔ)18——使用硬件QSPI讀寫<b class='flag-5'>SPI</b> <b class='flag-5'>Flash</b>(<b class='flag-5'>W25Q64</b>)

    剖析STM32F103讀寫W25Q64

    可說的。關(guān)于FATFS的移植下一篇文章介紹。本篇文章主要介紹W25Q64和驅(qū)動(dòng)函數(shù)。W25Q64容量是64Mbit的
    發(fā)表于 12-02 11:21 ?37次下載
    剖析<b class='flag-5'>STM32</b>F103讀寫<b class='flag-5'>W25Q64</b>

    Linux驅(qū)動(dòng)開發(fā)-編寫W25Q64(Flash)驅(qū)動(dòng)

    本篇文章就介紹如何在Linux系統(tǒng)下編寫W25Q64芯片的驅(qū)動(dòng),完成數(shù)據(jù)存儲(chǔ),W25Q64支持標(biāo)準(zhǔn)SPI總線,當(dāng)前驅(qū)動(dòng)程序底層的代碼寫了兩種
    的頭像 發(fā)表于 09-17 15:09 ?3400次閱讀
    Linux驅(qū)動(dòng)開發(fā)-編寫<b class='flag-5'>W25Q64</b>(<b class='flag-5'>Flash</b>)驅(qū)動(dòng)

    STM32驅(qū)動(dòng)W25Q64讀寫數(shù)據(jù)資料

    STM32驅(qū)動(dòng)W25Q64讀寫數(shù)據(jù)資料
    發(fā)表于 04-12 14:28 ?30次下載

    STM32 SPI讀寫W25Q64(二)

    W25Q64 將 8M 的容量分為 128 個(gè)塊(Block),每個(gè)塊大小為 64K 字節(jié),每個(gè)塊又分為 16個(gè)扇區(qū)(Sector),每個(gè)扇區(qū) 4K 個(gè)字節(jié)。
    發(fā)表于 07-22 11:09 ?6855次閱讀
    <b class='flag-5'>STM32</b> <b class='flag-5'>SPI</b>讀寫<b class='flag-5'>W25Q64</b>(二)

    STM32 SPI讀寫W25Q64(三)

    GPIO口模擬SPI讀寫W25Q64的基本內(nèi)容已經(jīng)跟大家介紹完了,今天跟大家介紹下如何通過串口接收文件并保存到W25Q64中。
    發(fā)表于 07-22 11:11 ?1643次閱讀
    <b class='flag-5'>STM32</b> <b class='flag-5'>SPI</b>讀寫<b class='flag-5'>W25Q64</b>(三)

    STM32驅(qū)動(dòng)FLASH(W25Q64)

    W25Q64 將 **8M** 的容量分為 **128 個(gè)塊(Block)** ,每個(gè)塊大小為 **64K 字節(jié)** ,每個(gè)塊又分為 **16個(gè)扇區(qū)(Sector)** ,每個(gè)扇區(qū) **4K 個(gè)字節(jié)** 。
    的頭像 發(fā)表于 10-24 09:50 ?1346次閱讀
    <b class='flag-5'>STM32</b>驅(qū)動(dòng)<b class='flag-5'>FLASH</b>(<b class='flag-5'>W25Q64</b>)
    主站蜘蛛池模板: 美丽的姑娘BD在线观看| 99热视频这里只有久久精品| 国产亚洲视频在线| 午夜人妻理论片天堂影院| 国产电影无码午夜在线播放| 熟妇久久无码人妻AV蜜桃| 国产精品视频国产永久视频| 午夜dj免费中文字幕| 国产一区二区不卡老阿姨| 亚洲精品喷白浆在线观看| 黑人寄宿羽月希产后奶水| 亚洲精品一线二线三线无人区| 狠狠色欧美亚洲狠狠色www| 野花影院手机在线观看| 久久热免费视频| 99精品视频在线观看免费| 欧美日韩视频一区二区三区| 成人在无码AV在线观看一| 四虎亚洲中文字幕永久在线| 国产香蕉九九久久精品免费| 亚洲天堂视频网站| 麻花传媒MD0044视频| md2.pud 麻豆传媒官网| 色噜噜色啪在线视频| 国产人成无码视频在线观看| 亚洲熟妇色自偷自拍另类| 快播成电影人网址| china年轻小帅脸直播飞机| 三叶草未满十八岁| 国产在线视频分类精品| 在线AV国产传媒18精品免费| 男女做爽爽爽视频免费软件 | babesvideos性欧美| 欧美一区二区三区男同| 国产精品久久久久影院嫩草| 亚洲精品午睡沙发系列| 快播h动漫网站| 成年AV动漫| 亚洲薄码区| 免费国产网站| 国产h视频在线观看免费|