你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103标准库开发---SPI实验---W25Qxx系列外部Flash芯片

[复制链接]
STMCU小助手 发布时间:2022-9-6 22:09
一、W25Qxx系列芯片----简介0 g" \3 d/ G; I) {
W25Qxx 系列 Flash 存储器可以为用户提供存储解决方案。擦写周期多达10W次,可将数据保存达20年之久,支持2.7~3.6V的电压,支持标准的SPI,还支持双输出/四输出的SPI,最大SPI时钟可达80Mhz。6 g/ J* K2 T: b) s+ X: f
W25Qxx 系列 Flash 存储器是为系统提供一个最小空间、最少引脚,最低功耗的串行Flash存储器,比普通的串行Flash存储器更灵活,性能更优越。
- q$ ~) c1 l8 M( [5 t# K; J功耗低,正常工作状态下电流消耗0.5mA,掉电状态下电流消耗1uA。9 \5 @7 I/ ]8 h5 k3 K6 b5 L$ ]

: L  q9 g  i2 l1. 存储结构. {% S1 f. H) @; ?! A3 m1 R. m
W25Qxx 系列 Flash 存储器的存储结构
! X; F" R$ C/ ?6 ?5 a相同点:/ B3 h# E- ^8 F, u# L+ n
' T8 e+ X0 P4 a2 W
1块 = 16扇区 = 64k字节,1扇区 = 16页 = 4k字节,1页 = 256字节。
3 |& X" C3 G, M( d% r只有三种擦除方式:扇区擦除 、 块擦除 和 全片擦除。
9 w, U* c. K1 o; m7 H) n写操作一次可以写1~256字节,最多一次写一页256字节。
( W0 i/ I+ I% r4 I3 [  P不同点: 容量和内存空间地址不同,具体如下表所示:
! l0 {) |2 `4 X( V' y
, ]7 L6 n) l/ G( F" a, u8 ~) @! O WVI1][T3@T_GHJ}Y0MIM@]D.png
& q# x5 {- D0 M4 g( v4 E, q. G& ~" h! u$ j/ _
2. 引脚接口
6 V; D$ d7 o2 f. f( y  M9 k下面只介绍标准SPI接口,接口如下图所示:
# I" }" g7 ?2 h# P+ D% H9 Y9 {# @4 b5 T# Y# b; V' ^$ e& k; W
747dfbc65d6a47bb94c2294f59f2484b.png 9 z; q5 w1 F, I' R! a/ z
* }( U; t2 {+ o- b3 U
片选引脚:/CS
+ C2 c8 M1 V# w: o(1)当CS引脚为高电平时,芯片被禁能,DO引脚高阻态,不能进行读写操作。( b2 }; k  h+ k$ \, b
(2)当CS引脚为低电平时,芯片被使能,能进行读写操作。, Z/ A/ e  c1 x9 t9 ^5 T
   上电后,执行一条新指令之前必须使CS引脚先有一个下降沿。* p# W$ Y! |6 ~( ~7 x

0 o( m8 Z( B. A0 U$ E7 P! W0 I数据输出引脚:DO(IO1)" r/ |* D, ]( w
标准SPI模式: CLK上升沿捕获地址和命令,下降沿输出数据。! @' @" U* l  i8 k& E1 r) ]0 g
QSPI模式: 双向数据传输 IO1。
; l9 S) ?7 f  a6 r7 B/ U/ @% S/ b
" I2 X. W$ D# `& K/ c写保护引脚:/WP(IO2)0 @/ B# G7 K, _
标准SPI模式:
/ s0 I, f: n  j# y- o) P- ~写保护引脚可以被用来保护状态寄存器不被意外改写。& E% R8 ]& B% A, j
(1)当WP引脚为高电平时,芯片写保护失能,可以正常写入数据。) L- s" T+ g7 C
(2)当WP引脚为低电平时,芯片写保护使能,不可以正常写入数据。/ s0 _5 P* h* }
QSPI模式: 双向数据传输 IO2。
% F) R) A" o9 W* x5 a  V
! b+ n& `- [* J, ?" U地:GND$ [. G  D4 `+ u4 ?4 {" {7 h$ I
电源地
! |1 c8 c" r  `+ u' t
7 B; B2 K9 r% ~( S& v# i9 @数据输入引脚:DI(IO0)
4 N9 ?% R2 i, v5 w3 {标准SPI模式:5 A' m2 p9 G/ p; o  s; e
数据、地址和命令从DI引脚送到芯片内部,在CLK引脚的上升沿捕获。- |3 b2 x) }" s" L
QSPI模式: 双向数据传输 IO0。" \; S+ R" q! g! V3 U1 [. O( P

9 c6 F5 Z* e5 f1 U! F串行时钟引脚:CLK) Q- t0 I6 f5 [4 s
SPI时钟引脚,为输入输出提供时序。5 _+ X" M+ Z- B  M
% N- G. X, l$ \6 j" Z
保持引脚:/HOLD(IO3)
, Y' w0 o) V  Z2 p" C4 D8 F2 S. e标准SPI模式:
, c. [5 e' E* L* L0 @/ ~当CS引脚为低电平时7 L, x. A1 f+ G- U" E2 G
(1)当HOLD为低电平时,DO引脚处于高阻态状态,而且也会忽略DIO和CLK引脚上的信号。, j; {( d+ R) m; t% A
(2)当HOLD为高电平时,芯片恢复正常工作。/ T- N! F5 D  P. x1 c9 D" V( l: i6 r. s
QSPI模式: 双向数据传输 IO3。- K9 F3 F* T% a7 z- L- u
& |2 u9 r& G6 D: i9 m6 r
电源:VCC( R' C: {) Q: s
电源正极, t2 L" C8 p( w6 I+ ?- r4 e. t
7 @; B8 B! q8 c% j
3. 原理图8 B8 A8 N, N) f8 y+ p, X

! b6 d* j( g+ P3 K) g8 @7 B
12f552454aa64e35b285542f7500306d.png
" ]2 ?0 p5 ]3 R) u+ z# H* g0 C$ y& T! ^# R: m* [+ P
4. 内部结构框架图
* K# f2 ^9 }9 `; |
8 ]! @1 V  v, z& k. |! Q; B: m8 C
cb09b34bf18d410596ed4466e685059d.png
6 m: k$ n& C; F5 b- Z  b4 H4 o2 a' a( S$ X( l1 [
5. 型号ID
0 _; \5 _* H' ?) c% h1 l1 D5 }. }* }
W25Qxx 系列 Flash 存储器支持 JEDEC 标准,具有唯一的 64 位识别序列号,方便区别芯片型号,具体如下表所示:
8 f* \9 a" M2 I (@K3TTZBLL~]80ZD30Q4]64.png
" ]% h+ x1 L* X- q) X1 g; P1 J
; V8 F! f- B$ j" l# Z$ D8 S
# P6 @* h/ G) M+ D1 B二、W25Qxx系列芯片----工作原理
: s9 Z4 x1 l5 f" X' a/ v1. SPI 运行方式

7 c* U) `& U0 ZW25Qxx系列芯片支持以下两种SPI通信方式:
( [. ~6 _; w6 g1 J2 o- ~% z& ]模式0: CPOL = 0,CPHA = 0$ u" A0 [& d: T- @% }$ |- Z
模式3: CPOL = 1,CPHA = 1
3 |( V+ m+ U4 Q2 A% v0 O) R
: l/ K: h2 I* v; Z% J' m: U4 B1 N2. W25Qxx系列芯片----状态寄存器
; V& U  w, s+ {/ J5 e! y注:这里是记录所有W25Qxx系列芯片的状态寄存器,有些型号的状态寄存器,没有全部功能。  Q, D$ }0 R- ^' Q
8 f9 K' M2 W2 @. i* I) y2 n( l
状态寄存器1
. @# k  c5 q# y( ]# }# `% M
% t7 [- g1 g. r* v8 h) ? %C~@RNU[)_}Z@L2)QZFA5.png 7 E; f& }( N" W
1 V( S2 P" i4 Y% h  y
S0----总线忙标志位(BUSY)5 `: H4 }1 ]$ |
在执行页编程、扇区擦除、块区擦除、芯片擦除以及写状态寄存器指令时,该位被硬件自动置1。这时候,除了读状态寄存器指令外的所有操作指令都会被芯片忽略。5 q" K. I: b( I8 s0 a, Q
当芯片执行完这些指令后,硬件会自动将该位清0,表示芯片器件可以接收其他的指令。: x4 s( P4 o, e
# |5 \$ e1 F5 s' g: X/ B
S1----写保护位(WEL)
2 {. \# ]# j% \7 T1 I$ u, |执行完写使能指令后,该位置1
! |+ w0 y1 D; p& A5 k# W  H当芯片掉电后和执行写禁能、页编程、扇区擦除、块区擦除以及芯片擦除指令都会进入写保护状态,该位置0" |/ D9 |7 D( z) [

/ S# U8 s2 n: I1 T5 v( o* |S2、S3、S4----块区保护位(BP2、BP1、BP0)
% o8 U2 H1 n$ t9 a% M/ k: l这3个位默认状态为0,即块区处于未保护状态。可以利用“写状态寄存器”指令对这几个位进行置1来达到块区保护的目的。块区保护状态为:没有保护、部分保护和全部保护状态。6 x3 R: K( A! D: f# i
当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这3个位不可被更改。
% P3 B% E: S" |$ @4 g8 h8 F0 t
7 `8 I3 k5 N6 k# D8 ?$ KS5----底部和顶部块保护位(TB)6 ?7 i8 P8 P1 L2 O9 ]" H
此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。5 S2 m3 D% ~. v5 m. e
当TB = 0时,表示保护位从顶部开始;3 Y$ Y, b- K! G) _" {
当TB = 1时,表示保护位从底部开始。+ f' c) ]6 ]9 k  ~4 k
当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这个位不可被更改。
& r# ^; Y, I  s& j0 U# M' M4 O* h3 t
S6----扇区/块保护(SEC)
  V$ N% R+ [$ ?8 ?此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。. s1 H9 H8 _/ U2 k8 g% P, x4 D
当SEC = 0时,表示每次保护的区域大小为4K;
; G) N4 U* d  z; o当SEC = 1时,表示每次保护的区域大小为64K。$ |$ x  k9 f7 f& |6 n# j6 |1 l
. w/ j  U& \) U9 h* F6 s8 ]% p
状态寄存器2
) W; Q) B& W- [  d
2 _  q; A% e+ l; L8 B. b
EBU]91I719ZNX5J~SI480EO.png : Q) ]- ~6 ^( Y3 P0 j( H
' k( T6 ^  i( z/ e/ H
S7、S8----状态寄存器保护位(SRP、SRL)
* k( k( g: v5 m+ \  L这两个位的默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。+ o+ w* D, A7 j9 D2 s; I
这两位和读写保护管脚(/WP)决定了状态寄存器写保护的方式。+ G8 b# {& N+ c, h5 O
状态寄存器写保护的方式有:软件保护,硬件保护、电源锁定或一次性可编程(OTP)保护。
2 t& x) h  U2 q/ N) X2 b5 [6 @' \- {1 W* g. J
S9----快速SPI通讯使能(QE)  Y: R6 z- b$ B+ |. o
此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。
# }! _) D; W% m4 Z* n" i- B当QE = 0时,设置为标准速度模式或快速模式,保持管脚(/HOLE)和读写保护管脚(/WP)启用;
3 j; f/ E2 q- g; x当QE = 1时,设置为高速模式,保持管脚(/HOLE)和读写保护管脚(/WP)被设置为IO2和IO3功能使用。
9 [" E) ?, u7 ]4 A
. T3 m" I0 h' ]0 V7 v% C, d/ sS10、S11、S12、S13----安全寄存器锁位(LB3、LB2、LB1)
* Q4 |- u* s6 l6 mLB3-1的默认状态为0,安全寄存器被解锁。) S7 Q3 Y0 J, f$ k2 S
可以使用写状态寄存器指令将LB3-1单独设置为1。2 ]. D0 _5 K8 X. ~& @: L5 B
LB3-1是一次性可编程(OTP),一旦它设置为1,相应的256字节安全寄存器将成为永久只读。% _% w* H/ K/ P1 O( t  c( i' J1 [
6 U( [# e* N4 z: F& _8 @) a$ ~
S14----补码保护位(CMP)- U9 @' i' ~* k7 \7 [/ p
它与SEC、TB、BP2、BP1和BP0位结合使用,为阵列保护提供更大的灵活性。
3 t& b* v9 @9 T. d0 ?6 c5 l一旦CMP设置为1,之前SEC、TB、BP2、BP1和BP0设置的阵列保护将被逆转。例如:& ?% T' X' l4 t" s- L. Z
当CMP=0时,一个最高64KB的块可以被保护,而数组的其他部分则不受保护;
+ x2 b  w0 y7 E2 T! z当CMP=1时,最上面的64KB块将成为不受保护的,而数组的其余部分将成为只读的。
1 e5 L: o, t" @/ ?: l  m2 _5 [  g默认设置为CMP=0。
, o9 \/ e' i! F' |+ y/ m$ l. k
, D9 J0 M% r7 b( F  RS15----暂停状态位(SUS)* c% x4 n+ @' `' {6 s+ w" b5 M
在执行**擦除/程序暂停(75h)指令后设置为1。
7 w8 e) v5 b7 {) Q" ?- ?通过擦除/程序恢复 (7Ah)**指令以及下电、上电周期将SUS状态位清除为0。
3 p& \6 R& h- Q8 W* P: e, e9 b# X  T) ~- Y+ n* n
状态寄存器3
. |4 t1 K; K# C, B& x( z" |9 X$ o
M7KOQ]@Q2E8YTH}`W]0NL2D.png ) A( F$ j* n" ~6 Z* U: q+ K  _1 `* C+ U
5 }8 x1 R- q- B
S16----当前地址模式(ADS)) E+ E4 M6 z, U( s1 j4 i! ^. Z
表示设备当前运行的地址模式。
8 `. a3 d+ ~! h1 r6 |当ADS=0时,设备处于3字节地址模式,! A' A+ [9 t" V, s7 j
当ADS=1时,设备处于4字节地址模式。& Z8 v! }( u3 V. S' t, |
0 `& I8 i% ]2 q! g
S17----启动时地址模式(ADP)
3 |$ i8 g' S& Z7 Z) ?& |& y0 S4 `2 B决定设备上电或复位时的初始地址模式,该位仅在上电或设备复位初始化期间使用。6 O! v/ j+ _+ [4 U; V$ I+ q/ B& m* B' g
当ADP=0(出厂默认)时,设备将启动到3字节地址模式,扩展地址寄存器必须用于访问超过128Mb的内存区域。当ADP=1时,设备将直接启动到4字节地址模式。# |, ?4 u& j3 G( k

1 r) e) J( s1 BS18----写保护方案(WPS)% r: ~" ]" |5 k: `
当WPS=0时,设备将使用CMP、SEC、TB、BP[2:0]位的组合来保护存储阵列的特定区域。
5 P3 U  L$ j; t' B当WPS=1时,设备将使用单独块锁来保护任何单独的扇区或块。
2 L- N: d( K- A' c) I3 E) z) e  O设备上电或复位后,所有单个块锁定位的缺省值为1。
( e) V# H& J; `1 w0 n8 f& q7 A7 n8 \6 q
S22、S21 ---- 输出信号强度(DRV1、DRV0)
" J" f0 x. I8 K/ _
% ^; h: a: t1 u2 Z) u) p bc43c9f8441f4eacac4548a5609f8e13.png , g: D9 o  E( @, ]& h+ t# R2 ]
* `) o; T9 [* o( |" k
S23----HOLD/RST引脚功能选择/ j7 K+ L' `+ z8 [/ d; |
当HOLD/RST=0(出厂设置)时,引脚为/HOLD。$ T& ^# ^: K& n& _8 q
当HOLD/RST=1时,引脚为/RESET。
# ?5 n/ i5 m6 G但是,只有当QE=0时,/HOLD或/RESET函数才可用。
) C, f" z/ B1 F( OQE设置为1时,关闭/HOLD和/RESET功能,引脚为专用数据I/O引脚。- }8 [, j- c  y" I0 f; s5 `2 h8 v
  ]7 \$ P. c/ o  ?- c) L4 A
3. W25Qxx系列芯片----常用操作命令% G0 C8 \# d0 g9 F, v) h6 B/ B
(1)单字节操作
6 L- s" t' n' i2 ~3 z: z单字节操作,只往芯片中写入1字节的操作命令,具体代码如下:
0 `" O! ~; L/ |2 I  b4 C& F. m! t
  1. void W25QXX_Write_Enable(void) //写使能 ( Q4 \  N6 N& i4 J
  2. {/ ^. r: M/ x, m4 g+ d# x
  3.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片
    5 M$ u: A2 k- M) b7 |
  4.         W25QXX_ReadWriteByte(0x06);  //写入1字节操作命令0 U, g) i- W; i& G; g) `5 N; y. Q; v
  5.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片        
    9 `+ U' v! J4 e$ D7 g2 D% Q
  6. }
复制代码

5 Z( x: y2 H2 a" ~0 t0 Z- n8 F1 m操作命令 如下表所示:
7 a) \5 ~: Y- e8 D( j6 x% r" y8 ~! S
B6K5[CC`CZQXLZSW{%%7QV2.png
* Z$ Y5 D. g, M 2XEKHJE0%]M3RGR3Q7]QZZ2.png
8 C& F1 w  C; x  R# x; c6 l# X! k1 F: m) f
注:如果想要实现其他功能,替换操作指令数据,便可实现功能。6 C' F6 j$ R) A, T
' G0 i" S6 W5 r' q' ~7 K! N3 O
(2)双字节操作
( V' h7 f$ c9 J) h0 x4 m/ c* P双字节操作,先往芯片中写入1字节的操作命令,接下来是读取/写入的字节数据。
; M& J. l. G0 a$ |+ p具体代码如下:# `7 J* \  L) A7 V/ \/ T/ n
1 w* ^& O( P+ r2 b1 o2 k( N' d
  1. //读取1字节数据
    " r) l/ h6 X! c1 k6 h
  2. uint8_t W25QXX_ReadSR(void)//读取状态寄存器! C/ G8 S1 r) ~' a7 U
  3. {
    , ?# m* S( K. s6 l
  4.         uint8_t  data=0;  f7 r& p) j3 {- L" H
  5.         W25QXX_CS(0);                             //拉低片选CS引脚---使能芯片
    ! }1 B8 z2 H9 ~9 v, b" E! `5 J
  6.         W25QXX_ReadWriteByte(0x05);           //写入1字节操作命令
    , L+ v% p8 |& e4 n; V( h  D% v# |
  7.         data=W25QXX_ReadWriteByte(0Xff); //读取1字节数据
    ; x8 s7 r& o7 h: \- Q
  8.         W25QXX_CS(1);                    //拉高片选CS引脚---取消片选. n; D5 L* `, K
  9.         return data;
    / {% S0 H3 C$ q" }
  10. }
    % H6 A/ w5 g% E) u- K9 w' y) M
  11. $ U# |2 F# a5 f. c: w
  12. //写入1字节数据4 Q" r, o( g3 S: G4 M* N
  13. void W25QXX_WriteSR(uint8_t data)//写状态寄存器# F6 V6 P1 E, p
  14. {
    - I3 a: V! ~" y- u* [" _
  15.         W25QXX_CS(0);                    //拉低片选CS引脚---使能芯片9 r  t: C: b" m% y2 `8 S2 Q
  16.         W25QXX_ReadWriteByte(0x01); //写入1字节操作命令
    - ?% W) @- ^# W
  17.         W25QXX_ReadWriteByte(data); //写入1字节数据# i2 R5 a! o% ~0 K3 K, ]1 c/ M. d( T
  18.         W25QXX_CS(1);               //拉高片选CS引脚---取消片选
    & @2 |% r* C9 B) g) A. P* a3 a, g2 @
  19. }
    & `3 K/ l3 `+ \) c; a) Y, o
复制代码
. ?( e5 e5 I' z2 n4 ]/ t. z. @/ t
操作命令 如下表所示:
) m0 R5 @# K8 y6 k
( U; ~( f1 U' O; v: m) W+ `# w M}40KHB2X}]JGPY1`RVOZGC.png % w, g" N* M6 I3 c
, w/ ]5 G2 S5 X7 h) E: H& r. r1 [
注:如果想要实现其他功能,替换操作指令数据,便可实现功能。- r7 i) ]' w( l0 T

' a: F: ?9 M5 C. D$ ?( W3 a' c6 b(3)读取ID操作4 l/ W( B2 q0 Z; \
具体代码如下:
8 i- n$ w' K- m5 i% I- A
: u5 _* X! v0 P! G% {" ?9 w( x
  1. uint16_t W25QXX_ReadID(void)//读取芯片ID# {0 e* Q  H) q8 a
  2. {
    " e  J/ E0 p$ y! l
  3.         uint16_t ID = 0;         
      ]" b  [4 b0 {/ V  z; `8 ?
  4.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片    # Q) Q3 m3 `' }2 h# S
  5.         W25QXX_ReadWriteByte(0x90);        //发送读取ID命令            
    - a+ m8 z! _0 g: n9 n
  6.         W25QXX_ReadWriteByte(0x00);             3 K% R8 ]2 e7 G; p1 h6 E
  7.         W25QXX_ReadWriteByte(0x00);            
    9 d! H8 }0 M8 l0 ?
  8.         W25QXX_ReadWriteByte(0x00);                                     1 K& x! P. O- A/ `
  9.         ID|=W25QXX_ReadWriteByte(0xFF)<<8;  . e, w2 c) |9 P' y- d* |! ^: b8 j1 n
  10.         ID|=W25QXX_ReadWriteByte(0xFF);         3 d" y1 j7 ~, ~2 S* U! R1 k! N
  11.         W25QXX_CS(1);                                 //拉高片选CS引脚---取消片选   
    $ d/ C5 y2 L, @5 A6 C1 ?  \
  12.         return ID;- z4 L9 U! q+ B3 M6 k
  13. }
复制代码
* E( ?8 w: T+ ~) [
操作命令 如下表所示:
) [- M  l. v! D9 l* ]6 U, ?' X+ M1 Z; ]2 R' [

/ k0 V9 x. W+ D  w9 {+ o  P9 L/ c1 G# d& }' r, B- |
指令名称        指令数据(hex)        字节1        字节2        字节3        字节4        字节5        功能& y  [+ P  O' j. ^7 d) w0 a. V
Device ID        0xAB        0x00        0x00        0x00        (ID7-ID0)                读取设备ID# y, `- L  D! f! B. `' H
Manufacturer/Device ID        0x90        0x00        0x00        0x00        (MF7-MF0)        (ID7-ID0)        读取制造商+设备ID2 h7 y) G4 o5 _. G( T. m
JEDEC ID        0x9F        (MF7-MF0)        (ID15-ID8)        (ID7-ID0)                        读取全部ID6 B( S! l  i0 U+ X' o. ]
Read Unique ID        0x4B        0x00        0x00        0x00        0x00        (UID63-0)        读取唯一ID号
- c( R) D9 x) T, r* q- C- l/ F% A注:如果想要实现其他功能,替换操作指令数据,便可实现功能。: c1 a! u* g, y, C+ ?" U7 o: H: d  u

0 @( q+ ?) R2 m6 i) Q; K5 s- b3 s(4)带地址操作
' O& i: ^) ?$ s' S$ O带地址操作主要分两种:
# H. B$ i# i4 G- J, v2 W% [* @* b3字节地址:W25Qxx系列芯片都可以使用。
4 Z1 `& [. q- D" m4字节地址:只有W25Q256和W25Q512可用。
7 ^# K$ |" x5 N4 y3 f) s5 F- L9 h5 M2 z; q4 E# X
3字节地址+ ?" r$ @, ?$ ^& l+ l$ n
具体代码如下:6 r" x. T: y0 Z7 _: t0 I1 s
  1. //读取数据1 x! o" [' ^9 i: Q$ [: Z8 v" T: L0 ^
  2. void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)   . ~. A' `+ ?- n0 B& [6 ?" }
  3. {                                                     ( ~4 l( n7 K; u4 p
  4.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片
    % y9 A; q* j; e4 q" _
  5.     W25QXX_ReadWriteByte(0x03);                            //发送读取命令  - \/ S6 ~; r$ X6 j4 _4 M+ Q+ a. b
  6.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>16));   //发送24bit地址   
    $ K: f% g1 c2 [- H
  7.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>8));   % |; n! W8 Q: \+ B/ q2 V
  8.     W25QXX_ReadWriteByte((uint8_t)ReadAddr);   
    / p' X4 a  S$ \+ T, q0 u4 @
  9.     for(uint16_t i=0;i<NumByteToRead;i++)//可读多个数据1 O# p! z, @# q% l/ d% h
  10.         { # e1 i6 l. m: C4 n7 T4 ]
  11.        pBuffer<i>=W25QXX_ReadWriteByte(0XFF);    //循环读数  
    6 n' ?3 _7 k8 \3 s- R4 X2 h$ V$ A
  12.     }5 j. l5 V3 @6 r5 T
  13.         W25QXX_CS(1);                                                  
    5 @* c# D+ N& d1 ^- c! O
  14. }  7 j7 J: D' m2 L
  15. : Q, d& Q. F9 g) X, c. s" f3 ]: S
  16. //写入数据
    ' V) {# R) ^- X8 J4 v( c# y
  17. void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
    : P0 {+ @( B2 n/ x5 l' `; e
  18. {3 y- w( ^* _; H+ L; w& w
  19.     W25QXX_Write_Enable();                          //写使能
    + H& i- X$ \0 ~; @+ t3 A+ H, ?
  20.         W25QXX_CS(0);                                    //使能器件   8 m0 ?5 D1 V* T2 [$ E- e8 q
  21.     W25QXX_ReadWriteByte(0x02);   //发送页写命令   / l, r$ |& l3 i4 M, O) x) n
  22.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>16)); //发送24bit地址    ) V% K0 n7 n& t6 D
  23.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>8));   0 f, Z+ E# f$ _
  24.     W25QXX_ReadWriteByte((uint8_t)WriteAddr);   
      c' _- X' j- Y9 p. @
  25.     for(uint16_t i=0;i<NumByteToWrite;i++)//可写多个数据,最多256个字节一页数据$ q. t- c3 h% m/ k$ d, u
  26.         {
    & T. D- h  r( g# Q: }1 Z5 s
  27.                 W25QXX_ReadWriteByte(pBuffer<i>);//循环写数  
    * H. ?6 G5 v. d  L
  28.         }8 t6 u, K. {. l) x
  29.         W25QXX_CS(1);                                    //取消片选
    4 k$ B6 u$ V# ^2 [: h+ Z/ a/ x5 z) M& h
  30.         W25QXX_Wait_Busy();                                                           //等待写入结束
    ! `! r+ z8 x; @, @" _+ C8 |
  31. } </i></i>
复制代码
2 X7 r) J( `( t  i0 b
操作命令 如下表所示:" C" h2 O# _, |8 h1 J
BM1@R5XOY96ST0QZ(X)BI0Y.png
' v7 V) q( p! j, b9 ]2 i$ N T%UQ7@4])){RN9[CCYV_D8Y.png
9 a8 s" }9 E0 E! A8 `
. z" A* s7 L2 K- y8 L* X% _- n4字节地址
  g! d6 x+ N# c( q8 Z具体代码如下:
( D, Z3 V. W1 f/ E! P. ~, s
  1. //启用4字节地址模式        , ~# j- C8 m& U4 y; ]4 g+ o
  2. void W25QXX_Enter_4Byte()1 x* c1 @* T7 U0 \* `+ t
  3. {
    ! T3 o) c$ H' @
  4.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片
    % l0 d" ?) [$ C3 q
  5.         W25QXX_ReadWriteByte(0xB7);  //写入1字节操作命令
    * S, D& G! r* E2 b1 q
  6.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片" Y  \+ D7 y  F% }# Y- n6 U
  7. }7 {. e# v/ Q- P) s9 A0 r. [: e
  8. 5 g6 K5 M/ c# l. H0 ?8 \( y, t
  9. //退出4字节地址模式        
    8 [! ]! Q0 C) X4 T
  10. void W25QXX_Exit_4Byte()
    0 i5 U6 E" l! B! R7 C6 C% r4 q
  11. {! ]7 ]0 ^  b8 C
  12.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片
    # `* B3 N8 t, L3 A0 Q( _
  13.         W25QXX_ReadWriteByte(0xE9);  //写入1字节操作命令  L  z3 v. c& A( B0 k  `
  14.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片
    0 z. B8 u5 v( {0 \, P
  15. }" Y/ M- o8 \# K3 ]* O! P
  16. & G3 N* O2 H5 d+ Z" c# J
  17. //读取数据8 {- n# _0 _. ?, u! ^2 J
  18. void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)   
    4 S+ ^' U( {4 h5 _4 |5 @6 s
  19. {                                                     ! ~; I- M, o, K3 p
  20.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片& q8 l; n7 |6 V( w; S1 r
  21.     W25QXX_ReadWriteByte(0x13);                            //发送4字节地址读取命令  1 K) `2 ?7 j& o
  22.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>24));//发送32bit地址
    1 |% t2 W$ S9 u
  23.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>16));     " @7 L1 a6 ~" F2 k9 f" _/ Z
  24.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>8));   ! z- @; y. f# I# ?& W2 y  Q0 A/ W
  25.     W25QXX_ReadWriteByte((uint8_t)ReadAddr);   - ^5 b/ W9 g1 Z5 C. e
  26.     for(uint16_t i=0;i<NumByteToRead;i++)//可读多个数据4 E1 W' z! g6 D, w) y( N
  27.         { 2 e' d- X0 W( f1 [+ H3 }) V3 E
  28.        pBuffer=W25QXX_ReadWriteByte(0XFF);    //循环读数  
    + S& Z. `% K  q. W; g
  29.     }
    ' D2 m5 q1 l3 k7 M5 N
  30.         W25QXX_CS(1);                                                  & C) a/ a7 W9 C$ g  m
  31. }  
      z, o4 M2 A* q' ?$ q3 U9 t
  32. 0 ]3 @, s7 l2 M! N" d$ ~. Q! ?4 N% K7 W
  33. //写入数据
    " n& [+ t7 a, X/ l! U$ |, b4 K9 @& o! L
  34. void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
    5 ^2 A( ?  {0 j2 l; O( j2 l) Y' S, X
  35. {
    & a  o3 j! A: M6 u& w! Z! d. o# k
  36.     W25QXX_Write_Enable();                  //写使能
    # F! t: X% R2 u9 W3 C
  37.         W25QXX_CS(0);                            //使能器件   
    4 a6 d+ }* P' l* I. E% H
  38.     W25QXX_ReadWriteByte(0x12);                           //发送4字节地址页写命令   ; A4 W5 {: v2 {( p* b" u$ M
  39.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>24));//发送32bit地址
    * y1 Z# B. r* Q2 O1 ]0 w: m
  40.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>16));    8 t7 q0 {" O5 X4 U: G  h
  41.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>8));   3 g1 t2 M# A! i! M9 \; i0 S# X
  42.     W25QXX_ReadWriteByte((uint8_t)WriteAddr);   
    / R4 c. h9 z& x$ b/ Z) e& ~
  43.     for(uint16_t i=0;i<NumByteToWrite;i++)//可写多个数据,最多256个字节一页数据
    9 u# d! G1 }* D" G
  44.         {
    ' t& S1 q6 N; |
  45.                 W25QXX_ReadWriteByte(pBuffer);//循环写数  
    + k& G4 P: {' S
  46.         }; `1 z, R4 u' X
  47.         W25QXX_CS(1);                                    //取消片选 * y( ?) q3 I9 T6 U0 }
  48.         W25QXX_Wait_Busy();                                                           //等待写入结束
    ( D5 z! e" Q$ K0 g5 |
  49. }
复制代码
; w7 l6 ~- M: {1 j: ~3 \
注:如果想要实现4字节地址,需要启用4字节地址模式。$ M/ ?+ b2 K7 F$ S
, I9 O( N% N# {1 @/ o1 ?$ z) |
操作命令 如下表所示:" v/ u3 V5 \6 y( c

: _$ T# P1 h* v+ z6 E9 X0 U1 x' W' p

4 E2 C  p8 t, V5 E# _5 _————————————————1 }# U3 l2 E- o# e
版权声明:根号五
3 B3 G! [0 `) P4 L0 l$ q: {" \& m% W7 j

4 a# A# ]8 x# A( @. b! W/ H4 ]
; X6 w3 s6 @0 {( e: |
6(AG%P$K@2WYM7L28}Z~2YC.png
28aa85ae89f54d22a0ac7f859f06dffb.png
0429d107819242b99ac4b1572581e79f.png
440efd4c84a849299dc4a781b30b43e4.png
d2e3010e09354c1a831211d35a40522f.png
收藏 评论0 发布时间:2022-9-6 22:09

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版