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

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

[复制链接]
STMCU小助手 发布时间:2022-9-6 22:09
一、W25Qxx系列芯片----简介
3 P  D8 s# f  y" B! ]: }W25Qxx 系列 Flash 存储器可以为用户提供存储解决方案。擦写周期多达10W次,可将数据保存达20年之久,支持2.7~3.6V的电压,支持标准的SPI,还支持双输出/四输出的SPI,最大SPI时钟可达80Mhz。
& N. @& U- _3 n4 @# i5 i6 ]W25Qxx 系列 Flash 存储器是为系统提供一个最小空间、最少引脚,最低功耗的串行Flash存储器,比普通的串行Flash存储器更灵活,性能更优越。
8 r; A( M! w6 l功耗低,正常工作状态下电流消耗0.5mA,掉电状态下电流消耗1uA。) U% W) I/ n4 }, Y. D
$ \: C" y$ \, ]% P# C
1. 存储结构
8 ^' {! o( H, ]; j, d9 r4 D/ c+ T( N. jW25Qxx 系列 Flash 存储器的存储结构
- l; U. P! s) K: {. T. Y相同点:- e5 J: e$ i1 F4 W8 a$ o
$ p( y% @8 g# X2 U, W8 j6 r# t
1块 = 16扇区 = 64k字节,1扇区 = 16页 = 4k字节,1页 = 256字节。
$ m1 ^' B: @/ v; ^/ q" h只有三种擦除方式:扇区擦除 、 块擦除 和 全片擦除。
! x' j8 V( S. [3 m# Z: u$ T4 }写操作一次可以写1~256字节,最多一次写一页256字节。6 h  K* I2 J! y* V) b
不同点: 容量和内存空间地址不同,具体如下表所示:
) G- Y; v. w! S7 A
- j8 k' E# T; G* I; E- x WVI1][T3@T_GHJ}Y0MIM@]D.png 3 {$ M6 S+ j: _$ B; w

- `; b0 W6 X( Z+ n0 w) t2. 引脚接口
/ n! W4 Q) `* T' i下面只介绍标准SPI接口,接口如下图所示:; ]: R) m+ R# ]' L+ A

8 V; q( v# {- f, `, c 747dfbc65d6a47bb94c2294f59f2484b.png 3 H5 s0 A5 g5 Y% R8 E
* X9 E5 ^( O, Y4 I) w
片选引脚:/CS
* D& L$ X$ n6 A1 p(1)当CS引脚为高电平时,芯片被禁能,DO引脚高阻态,不能进行读写操作。( x) R9 M8 t' U8 l( n+ H
(2)当CS引脚为低电平时,芯片被使能,能进行读写操作。7 z* E/ `) t5 i6 ]$ i! o  O
   上电后,执行一条新指令之前必须使CS引脚先有一个下降沿。
9 y. }; r' @; E- J0 V2 H) M: G5 h5 |6 Z# f7 {& L
数据输出引脚:DO(IO1)0 M1 P6 I" T0 V8 W( t( y% t
标准SPI模式: CLK上升沿捕获地址和命令,下降沿输出数据。- y8 E) G' j* ?8 ^9 z& a2 `# X
QSPI模式: 双向数据传输 IO1。
0 N, q# I& ?+ x+ A% Y7 w( l  T
  S' s  y# a$ i6 O, w7 R写保护引脚:/WP(IO2)4 k1 t! i8 H/ S, E8 S" O% r& I( P
标准SPI模式:0 s. p! R; o* V' u6 Y5 |1 S, q
写保护引脚可以被用来保护状态寄存器不被意外改写。% g. [9 T1 }) V# X1 Y! r4 `5 k7 g) S
(1)当WP引脚为高电平时,芯片写保护失能,可以正常写入数据。  B# b; _+ _2 \1 Q7 g
(2)当WP引脚为低电平时,芯片写保护使能,不可以正常写入数据。
9 w$ f6 C2 D: \: d# N6 Z2 GQSPI模式: 双向数据传输 IO2。
9 d( j: `; e. _8 ~  g
( W; F$ Q! ]/ Q3 X  u; H地:GND
6 t" B  G% ^7 z( p, C电源地
* R- l% X: G+ w7 p, x2 D2 W$ o9 y; f4 b( V
数据输入引脚:DI(IO0)) z% u( V, S4 g5 Q" w
标准SPI模式:
/ R( h- o7 C2 v/ K6 J$ y% Z数据、地址和命令从DI引脚送到芯片内部,在CLK引脚的上升沿捕获。# N/ N5 D+ e( Q/ H3 T* `9 c, m
QSPI模式: 双向数据传输 IO0。
- o6 o7 A; u2 \2 H) r8 y
" e4 ~- i# ~# h0 l串行时钟引脚:CLK
: `/ f, ~0 Q1 p$ g% K: k8 E% ISPI时钟引脚,为输入输出提供时序。! a8 R: m; h9 ~; E1 H+ Y

6 t5 K$ E% Q$ f# h; a保持引脚:/HOLD(IO3)9 ?: M' `6 @* ?: M/ n
标准SPI模式:9 X# ]$ ^; n2 b, q) L
当CS引脚为低电平时, j" R$ w$ q9 A3 i, g/ `( M; w
(1)当HOLD为低电平时,DO引脚处于高阻态状态,而且也会忽略DIO和CLK引脚上的信号。' F( o( r# z9 @0 r* n4 `4 B) C
(2)当HOLD为高电平时,芯片恢复正常工作。
0 l8 B5 p: g; L/ V" w3 B9 pQSPI模式: 双向数据传输 IO3。
# j; I: i5 x3 _; u: p: B1 v+ J% |) m6 w& O/ C
电源:VCC
4 G$ P+ ^: a- P' V" U电源正极
: q. O$ ?& ]$ f1 x! A& _: `* l' {* _6 D# k" W6 i+ i& ?
3. 原理图
6 z$ @3 b1 S+ N. T7 G* f
; {$ a! _3 C" j, ]/ U; I
12f552454aa64e35b285542f7500306d.png , d1 s. T% e+ k" F( g
8 u1 G2 i- @# y/ `4 i& n4 l
4. 内部结构框架图
, h' X: X4 X6 R" N( p1 H7 J
2 m7 I! K1 i* i8 y. R
cb09b34bf18d410596ed4466e685059d.png & b) k0 S: }* N1 y5 U% Y& ~3 Q
  m  [6 e* q0 P
5. 型号ID
; x( Y' C. M0 ?' M8 U: D
W25Qxx 系列 Flash 存储器支持 JEDEC 标准,具有唯一的 64 位识别序列号,方便区别芯片型号,具体如下表所示:8 x- m1 d. E7 O
(@K3TTZBLL~]80ZD30Q4]64.png / M! S  z" T6 N/ J9 ^
) O' t& b* h  z. v4 T4 q! O3 W9 @

+ F4 Y8 E5 ~: Q  e4 ^二、W25Qxx系列芯片----工作原理, ^; Q( j- q3 l9 E
1. SPI 运行方式

: q! _! o0 U2 S: ]. N9 j' f2 d+ fW25Qxx系列芯片支持以下两种SPI通信方式:* C3 O- a2 T% v0 N+ ?
模式0: CPOL = 0,CPHA = 01 q6 ]" ^3 m1 d$ t2 D: @6 B; g
模式3: CPOL = 1,CPHA = 1
4 ?+ v& o" m. O* {( b; `5 R1 x( _2 t# U8 k
2. W25Qxx系列芯片----状态寄存器
8 ~7 I1 _6 \7 A: g+ \5 X6 ~注:这里是记录所有W25Qxx系列芯片的状态寄存器,有些型号的状态寄存器,没有全部功能。6 }/ a  ^" w/ N2 P0 _

/ j' s9 N+ s/ m0 z5 d9 o状态寄存器1
+ B4 J- R7 z5 t! S9 _
( ^! B4 e9 I2 t/ K. c' U* z %C~@RNU[)_}Z@L2)QZFA5.png / U0 Z7 v8 T' z

$ @' a1 _% s3 l  BS0----总线忙标志位(BUSY)
$ M+ o4 d% s* p+ P, R在执行页编程、扇区擦除、块区擦除、芯片擦除以及写状态寄存器指令时,该位被硬件自动置1。这时候,除了读状态寄存器指令外的所有操作指令都会被芯片忽略。7 h2 N! @3 t7 D3 h1 d
当芯片执行完这些指令后,硬件会自动将该位清0,表示芯片器件可以接收其他的指令。
" S7 _  Z, Q! j* [4 L5 R
* y8 E  m) c' Y. C& z) uS1----写保护位(WEL)) `, m! h. Q  `" W1 j7 T
执行完写使能指令后,该位置1
. N) ~5 g/ R/ v. T当芯片掉电后和执行写禁能、页编程、扇区擦除、块区擦除以及芯片擦除指令都会进入写保护状态,该位置0
" p. a" G6 f/ V
- ]6 L; j2 \- ~" f$ [7 `* M# U0 ]$ OS2、S3、S4----块区保护位(BP2、BP1、BP0)( ^8 ~% ]' r& g$ Z0 K
这3个位默认状态为0,即块区处于未保护状态。可以利用“写状态寄存器”指令对这几个位进行置1来达到块区保护的目的。块区保护状态为:没有保护、部分保护和全部保护状态。
! @; ^1 }! n4 ]. K当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这3个位不可被更改。
4 }# S) b3 V) j+ l3 o: z5 b
) o5 I9 q4 F& `0 B- w/ m( Z1 u' WS5----底部和顶部块保护位(TB)6 O: N6 t6 v( p; s* A  z- ]
此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。+ v: d! l  `; `$ Z8 o3 u6 n8 p2 t
当TB = 0时,表示保护位从顶部开始;$ L/ i, Y; p' u- ^: V+ R, S6 P' r
当TB = 1时,表示保护位从底部开始。0 \3 Z! U8 S2 p1 L2 U  {3 }
当状态寄存器的SRP位为1或读写保护管脚(/WP)为低电平时,这个位不可被更改。% ^0 Q% h4 c/ P) k: m+ n
2 C% @. |+ ^+ n$ r1 s* U
S6----扇区/块保护(SEC)& F; `0 T: j' X/ {0 l
此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。
7 M( b4 g/ g% G" ^6 m( O/ g当SEC = 0时,表示每次保护的区域大小为4K;
8 w+ _+ {7 i% D4 y当SEC = 1时,表示每次保护的区域大小为64K。
& K6 A  N- Q8 y1 M! ?" h8 n( ?- P/ k( w6 B
状态寄存器2
. {2 U" ?: h; A% ?  }
. E- p3 C" u. y3 c, R
EBU]91I719ZNX5J~SI480EO.png 1 X. v+ E7 `! K: i

: G- H0 h, Q& j1 l: F1 sS7、S8----状态寄存器保护位(SRP、SRL)) o, H2 ^9 y: k
这两个位的默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。5 @& p/ w' ]5 j( T% U
这两位和读写保护管脚(/WP)决定了状态寄存器写保护的方式。
$ [5 R, E! V3 M( [, {/ @状态寄存器写保护的方式有:软件保护,硬件保护、电源锁定或一次性可编程(OTP)保护。( y" L& y+ Q4 z% S

9 F$ z# ?7 T# y, E% tS9----快速SPI通讯使能(QE)
! Q$ ~9 p* z# l+ W此位默认值为0,可以利用“写状态寄存器”指令对这个位进行置1或清零。
6 N$ x' t. Z" _2 g8 y8 g2 ]当QE = 0时,设置为标准速度模式或快速模式,保持管脚(/HOLE)和读写保护管脚(/WP)启用;
! G" R$ |  |$ C& _$ L1 o! t当QE = 1时,设置为高速模式,保持管脚(/HOLE)和读写保护管脚(/WP)被设置为IO2和IO3功能使用。
* `& X! c5 F, [4 r- p3 M9 z2 N6 [/ R: k* ]" p
S10、S11、S12、S13----安全寄存器锁位(LB3、LB2、LB1)
* l( e& Y3 v: F$ V& vLB3-1的默认状态为0,安全寄存器被解锁。+ g. `' |" ^* W" i+ g
可以使用写状态寄存器指令将LB3-1单独设置为1。
) J, d; B" p+ G4 O2 w7 c& @* zLB3-1是一次性可编程(OTP),一旦它设置为1,相应的256字节安全寄存器将成为永久只读。
  h# o! t2 i+ S8 I. k4 c2 \+ Y' p6 {  W* |! g5 y$ W) o* k  }
S14----补码保护位(CMP)
# r9 f7 _. \( j它与SEC、TB、BP2、BP1和BP0位结合使用,为阵列保护提供更大的灵活性。
  T9 V( g3 N, _7 v" v1 A" p一旦CMP设置为1,之前SEC、TB、BP2、BP1和BP0设置的阵列保护将被逆转。例如:2 `" j! o$ Y& `0 ^/ m: q
当CMP=0时,一个最高64KB的块可以被保护,而数组的其他部分则不受保护;9 v# f+ l1 g7 N5 J. _
当CMP=1时,最上面的64KB块将成为不受保护的,而数组的其余部分将成为只读的。# r& `: v% v8 d' R4 q0 v1 z2 F
默认设置为CMP=0。+ m( F, d5 Z4 m5 Q- G9 X- P
  R& x6 z5 A* s
S15----暂停状态位(SUS)
  [& r) I& ?7 h& c6 j: ?+ Z在执行**擦除/程序暂停(75h)指令后设置为1。8 B3 d6 K& r! E% L- Y# e
通过擦除/程序恢复 (7Ah)**指令以及下电、上电周期将SUS状态位清除为0。
  s6 ~. g3 v- n( V
- f+ a: p2 O0 o' \# F+ ^状态寄存器3  g9 @) L/ `; W- j' U* L. g8 l* f

. x2 q! n# Q; ]! I6 N9 K( @! ] M7KOQ]@Q2E8YTH}`W]0NL2D.png
" C6 C* h, Y4 z. L$ K, C0 |. }4 ]0 C) y. t2 Q* c, `/ z. N8 I0 f% \
S16----当前地址模式(ADS)* X4 i7 [$ j* f+ t
表示设备当前运行的地址模式。# d4 K, L9 x9 L+ D& `
当ADS=0时,设备处于3字节地址模式,
) e% K( W, N" q+ e8 }8 r2 r当ADS=1时,设备处于4字节地址模式。
3 M8 U! V3 j8 Z7 P) D/ X" H' y. E
: U  o. ^. j$ G# ?. c8 t3 P2 Q" yS17----启动时地址模式(ADP)# q4 F8 c9 k8 M  z& n& }
决定设备上电或复位时的初始地址模式,该位仅在上电或设备复位初始化期间使用。' B3 S6 W7 Y) Y
当ADP=0(出厂默认)时,设备将启动到3字节地址模式,扩展地址寄存器必须用于访问超过128Mb的内存区域。当ADP=1时,设备将直接启动到4字节地址模式。2 B' p4 i# r- Q  N! ~5 F
* d7 [+ o% Y- r+ [' p$ {, x
S18----写保护方案(WPS)) f7 l6 x4 F* H
当WPS=0时,设备将使用CMP、SEC、TB、BP[2:0]位的组合来保护存储阵列的特定区域。; A% K; g: ?9 ^7 ]! v; x; Q7 L/ ]
当WPS=1时,设备将使用单独块锁来保护任何单独的扇区或块。4 T9 w1 c7 R+ a2 Q. k* |
设备上电或复位后,所有单个块锁定位的缺省值为1。
. h) A7 H, j. F* s% B. m8 M: o" `5 i5 B! R2 M$ i
S22、S21 ---- 输出信号强度(DRV1、DRV0)9 A0 b* i; k% |8 w; w/ F0 k5 s

( @* T1 u. E$ Y! T9 w4 V5 `6 u bc43c9f8441f4eacac4548a5609f8e13.png & ~- S) _# d2 L/ a1 A$ I  c: B- y

2 _& f0 w( |: M  j' R: s* j; J: mS23----HOLD/RST引脚功能选择
& l: z8 Q2 `' q7 I/ p当HOLD/RST=0(出厂设置)时,引脚为/HOLD。
% S  ~) C/ u9 p0 K5 Q: u1 ]- C当HOLD/RST=1时,引脚为/RESET。" X& Z- R. A- e$ D( y
但是,只有当QE=0时,/HOLD或/RESET函数才可用。8 e( J5 z* t1 B, x2 @
QE设置为1时,关闭/HOLD和/RESET功能,引脚为专用数据I/O引脚。. y" ]& Y3 }3 o! ?

" F# [7 v) ]8 @3. W25Qxx系列芯片----常用操作命令0 L3 @: i! n5 S" l
(1)单字节操作; h0 ^7 Y4 c* ?4 r! I
单字节操作,只往芯片中写入1字节的操作命令,具体代码如下:
5 c5 f) [- R' a+ H, {9 {' _, p: G# I- n- x1 R% G
  1. void W25QXX_Write_Enable(void) //写使能
    ) k0 G9 n( T$ j* E$ S& H4 ?
  2. {! J  q( \! W2 _* k
  3.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片7 y( {. I: A* m) @) i
  4.         W25QXX_ReadWriteByte(0x06);  //写入1字节操作命令$ \3 ]  t( m  M4 C. y
  5.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片        
    2 m: ^  E2 \- W6 x% k5 R" {6 Y0 p
  6. }
复制代码
+ G) s6 S# k* ^0 `; m) A* |" ?
操作命令 如下表所示:
. B: z: s3 `8 k, {; [& ~; ~$ w5 M$ {8 Y
B6K5[CC`CZQXLZSW{%%7QV2.png
, G! m- W9 M/ p4 Q. m5 E  X. l 2XEKHJE0%]M3RGR3Q7]QZZ2.png
3 Q7 ?  Z+ _  U( R8 D9 O
: x% P; R7 ^' {) F注:如果想要实现其他功能,替换操作指令数据,便可实现功能。( e6 j, E( E( _+ ?, l

% `& ~& J6 w' w7 [- t) }8 W0 _% V(2)双字节操作
5 D5 o+ P: c3 w% M/ }+ G! |双字节操作,先往芯片中写入1字节的操作命令,接下来是读取/写入的字节数据。; o$ {+ j8 x& f4 ~2 D2 y
具体代码如下:+ n3 D, I: Q" B6 i1 v

  r) {3 v. r. B+ ~# k- B0 n) @
  1. //读取1字节数据
    2 e  n! |& y9 C
  2. uint8_t W25QXX_ReadSR(void)//读取状态寄存器6 c0 U; M) B6 _+ C& m
  3. {
    3 K4 F+ d4 O( t* N1 i- W: i$ {- G. s0 w+ Y
  4.         uint8_t  data=0;
    ' c2 o3 P% k; ]' ]' G( g
  5.         W25QXX_CS(0);                             //拉低片选CS引脚---使能芯片
    # ]& Y( c0 v) k7 n" i7 ?8 m9 s' I
  6.         W25QXX_ReadWriteByte(0x05);           //写入1字节操作命令. q# R4 N% j5 s3 B: `
  7.         data=W25QXX_ReadWriteByte(0Xff); //读取1字节数据- g" q& t( v8 S6 Z" c, k$ W( m
  8.         W25QXX_CS(1);                    //拉高片选CS引脚---取消片选
    . v, u( \8 Z5 }) ~
  9.         return data;2 m2 o- c# M5 f5 ?/ R. w0 K
  10. }/ l% R5 l& `0 X/ e" d) [

  11. 6 N& D' ~: `4 z
  12. //写入1字节数据
    / H1 ?4 N3 b6 M
  13. void W25QXX_WriteSR(uint8_t data)//写状态寄存器
    * }5 k( [- T! a, z9 B  T% D
  14. {! Z& P4 I. l3 \
  15.         W25QXX_CS(0);                    //拉低片选CS引脚---使能芯片
    " x  t) N  B9 W: c4 d: U, W
  16.         W25QXX_ReadWriteByte(0x01); //写入1字节操作命令1 v8 k' C- J- W6 N8 L4 c
  17.         W25QXX_ReadWriteByte(data); //写入1字节数据
    " i8 }/ `: N4 ^3 m0 e% k2 O# L
  18.         W25QXX_CS(1);               //拉高片选CS引脚---取消片选" N4 B% ]  ?& I
  19. }- e5 R6 H3 S2 C7 b( u3 o
复制代码

$ Z2 R, l. g, u% R, O操作命令 如下表所示:; P4 x9 a" f8 T& C' i, Q# K

' D$ h9 d: u+ l M}40KHB2X}]JGPY1`RVOZGC.png ( I" k  k' n9 h7 b- b
& V9 D3 D! N9 g/ Q7 C1 C2 f1 w) K
注:如果想要实现其他功能,替换操作指令数据,便可实现功能。
3 o' b2 F  A% v- v* F! h$ F3 e. E
: ]$ U7 |+ d) Z0 c: ~(3)读取ID操作# {6 `# a& L8 N' {
具体代码如下:
9 Z: N9 ~+ t, J4 u$ q* ?
0 c4 n7 N4 ~& A1 B4 |3 D9 I
  1. uint16_t W25QXX_ReadID(void)//读取芯片ID
    # T$ ]1 u. n5 d! r" K2 g! V& M
  2. {
    $ C$ Z2 G- w4 U& F) ?/ ]+ U
  3.         uint16_t ID = 0;          4 g, G2 I7 ~& k1 x! m8 j: K/ U
  4.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片   
    $ A* a/ d5 Q" M" z6 k
  5.         W25QXX_ReadWriteByte(0x90);        //发送读取ID命令            : V0 h9 {( ^. P. d
  6.         W25QXX_ReadWriteByte(0x00);            
    3 D: y, K0 g# ]" t2 T
  7.         W25QXX_ReadWriteByte(0x00);             / ~+ y8 U" @# B( Q$ k8 }
  8.         W25QXX_ReadWriteByte(0x00);                                    
    # d+ D3 o  L! p) ]! \4 q6 J
  9.         ID|=W25QXX_ReadWriteByte(0xFF)<<8;  
    4 F, @( v! K* D) X. d
  10.         ID|=W25QXX_ReadWriteByte(0xFF);         
    / Y5 _  \) ?+ m) E- F/ ~
  11.         W25QXX_CS(1);                                 //拉高片选CS引脚---取消片选   
    ! U% S8 o# g! s# }
  12.         return ID;- |  Q$ P0 P; Q9 L1 w: a7 |% i
  13. }
复制代码
9 U1 J$ \( o# H3 v$ ^; q0 J
操作命令 如下表所示:
  u8 \# Z$ y; H5 A9 D! m" X$ i/ ^; ~$ h" e# p1 C( ^$ T: L' c

7 @0 y0 S4 z  |) }1 I
8 N# Q5 A" |; Z2 y% o指令名称        指令数据(hex)        字节1        字节2        字节3        字节4        字节5        功能1 J! ^8 z1 M) C9 z
Device ID        0xAB        0x00        0x00        0x00        (ID7-ID0)                读取设备ID7 ^2 b" P# g  `( V9 w
Manufacturer/Device ID        0x90        0x00        0x00        0x00        (MF7-MF0)        (ID7-ID0)        读取制造商+设备ID
- c! ?" H5 k0 t4 S$ v5 NJEDEC ID        0x9F        (MF7-MF0)        (ID15-ID8)        (ID7-ID0)                        读取全部ID
! M# U$ i6 R% r- E$ R$ bRead Unique ID        0x4B        0x00        0x00        0x00        0x00        (UID63-0)        读取唯一ID号6 V6 \8 f7 G2 e
注:如果想要实现其他功能,替换操作指令数据,便可实现功能。
6 F3 T+ J" [. Z4 Z0 M2 F; O, H% r$ B* i6 R1 }5 N
(4)带地址操作7 h7 X" k% R% Z, ^3 \
带地址操作主要分两种:( X: k1 I; v  V
3字节地址:W25Qxx系列芯片都可以使用。
3 @9 b& Z5 N" M1 Z  C9 T4字节地址:只有W25Q256和W25Q512可用。
7 _0 f0 y( }$ l* w5 d
) ?0 [, q" j4 k3字节地址$ G+ V/ K1 S0 L* f9 U7 I
具体代码如下:' D% Z7 K( m5 E; l3 J1 E, ^) F' j- j
  1. //读取数据
    / o. z/ d9 c1 o
  2. void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)   
    ' g4 d/ s: @+ @- L# _* P' j/ X# R9 W
  3. {                                                     $ _% k) l! |' i. x7 ]" k
  4.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片; F7 S& [; c1 M* i/ h
  5.     W25QXX_ReadWriteByte(0x03);                            //发送读取命令  $ F) U( z; @2 D
  6.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>16));   //发送24bit地址    4 O5 Q% f6 ^; t5 _  P
  7.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>8));   
    ' _% ?6 Z9 V' }) O: b& d2 p
  8.     W25QXX_ReadWriteByte((uint8_t)ReadAddr);   
    $ {  M; |5 S. q$ D  o
  9.     for(uint16_t i=0;i<NumByteToRead;i++)//可读多个数据9 N& [* h2 D( z" T- o0 {
  10.         {
    : a$ V( h" n6 S/ p. B' j2 n  Q
  11.        pBuffer<i>=W25QXX_ReadWriteByte(0XFF);    //循环读数  % H3 c. u/ l9 |- }5 {- J0 \" ^
  12.     }
    / V1 N4 P4 X$ l5 I
  13.         W25QXX_CS(1);                                                  
    7 l/ h. A6 H% f0 A0 ]
  14. }  & B% m0 O0 E& a* Y' Z( c( v

  15. ( V  Z; a7 N4 N) {: s
  16. //写入数据4 o5 U; U5 b* ?) Y' b0 r0 a
  17. void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)3 z5 T7 n# D$ m, Z* I+ T! H. w  _
  18. {9 |3 H+ b# U, i4 ]1 |
  19.     W25QXX_Write_Enable();                          //写使能
    % {, T0 S$ Q' V7 M6 R( ^) M
  20.         W25QXX_CS(0);                                    //使能器件   
    2 H5 ~1 d2 c: b" v. x& t
  21.     W25QXX_ReadWriteByte(0x02);   //发送页写命令   ) W# e/ x( ~; U
  22.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>16)); //发送24bit地址   
    5 s' ~! x' z9 [% ]. d$ r9 `4 v
  23.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>8));   / p0 {  M. U' I+ t. t
  24.     W25QXX_ReadWriteByte((uint8_t)WriteAddr);   6 M1 I+ O3 ?+ J. Y: H
  25.     for(uint16_t i=0;i<NumByteToWrite;i++)//可写多个数据,最多256个字节一页数据" \( a4 v& Y& f
  26.         {
    % n, S' q. u  F7 ]3 }$ Q4 ?( m
  27.                 W25QXX_ReadWriteByte(pBuffer<i>);//循环写数  
    . U3 ?5 X/ R" N$ I' J
  28.         }4 I* I$ Z( x7 J' E) i
  29.         W25QXX_CS(1);                                    //取消片选
    7 p% ^/ I0 y1 o; |
  30.         W25QXX_Wait_Busy();                                                           //等待写入结束5 E0 K- h( j* @# f5 Q. B
  31. } </i></i>
复制代码
3 }  C! S% B6 F8 n
操作命令 如下表所示:, Z  m( o+ V: K: ^& B/ A  ~
BM1@R5XOY96ST0QZ(X)BI0Y.png
5 i8 ~) @5 ~( z5 G) E; \- k1 C T%UQ7@4])){RN9[CCYV_D8Y.png
8 X: z+ l/ H) ~- G. z
+ A. l3 w' _; g! p& {6 F; M4 H4字节地址5 S0 h: ]1 w7 o7 o6 n7 z- U' F
具体代码如下:; M; _7 r- ^! g% Z" p& b$ f
  1. //启用4字节地址模式        8 m/ L, \( n& h! H3 x) x* U
  2. void W25QXX_Enter_4Byte()
    9 d: V( G3 q1 ^+ t0 e% `
  3. {
    ; k  j9 ~7 A# Y, r
  4.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片
    + T3 w0 c* ]/ i0 V" X( e3 Z% G
  5.         W25QXX_ReadWriteByte(0xB7);  //写入1字节操作命令' Z6 n: v6 K5 ^3 O; c& x
  6.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片1 F4 p! N+ r; e1 M' H
  7. }
    & V& B# C. H5 v$ c
  8. ; f  S9 {- {( X5 T
  9. //退出4字节地址模式        2 d# ?0 Z- j/ \4 k; ?/ \
  10. void W25QXX_Exit_4Byte(): c" z- Y3 J) ?
  11. {! `; l/ s, G  }1 B
  12.         W25QXX_CS(0);                                 //拉低片选CS引脚---使能芯片
    4 M& D3 L) K3 I* _# K. N
  13.         W25QXX_ReadWriteByte(0xE9);  //写入1字节操作命令3 O9 s# f/ r* P7 U4 l9 Z& R0 C
  14.         W25QXX_CS(1);                                 //拉高片选CS引脚---关闭芯片0 w; J1 }( _7 Y# J4 n* ~
  15. }$ x' X4 ]. o) c% |0 d

  16. 1 [- t; s) l' P( }% j" v
  17. //读取数据
    4 }  ]# P- L, d# [* b) x
  18. void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)     l7 g: S; ?% a) Y! e
  19. {                                                     + i/ C8 y( Z% T( c
  20.         W25QXX_CS(0);                                //拉低片选CS引脚---使能芯片5 R) c3 Y( _8 `& M/ I
  21.     W25QXX_ReadWriteByte(0x13);                            //发送4字节地址读取命令  
    0 K# f' I- _5 G9 s
  22.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>24));//发送32bit地址
    # Q& J, r( C5 A0 ]9 }
  23.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>16));     & D* D! C7 w5 ^- y1 }+ W
  24.     W25QXX_ReadWriteByte((uint8_t)((ReadAddr)>>8));   , @9 k6 C9 }. ^; z  N5 K
  25.     W25QXX_ReadWriteByte((uint8_t)ReadAddr);   , n! ]5 t/ W# h* `8 M7 T# \
  26.     for(uint16_t i=0;i<NumByteToRead;i++)//可读多个数据
    2 [+ |( W* V3 k+ T& o- m: B
  27.         { / a' i0 H( R5 L9 t  u' v8 d& N
  28.        pBuffer=W25QXX_ReadWriteByte(0XFF);    //循环读数  ' e; r( M; x# \1 J+ s% |1 l
  29.     }
    2 a# m3 w7 \/ q- F3 B
  30.         W25QXX_CS(1);                                                  ' [0 r" q8 B% ^1 Q3 f3 Z" m7 h+ c/ D
  31. }  
    # b3 y7 o( j& \( H2 A- o$ q
  32. 4 Y, k5 j7 f( S( N, \
  33. //写入数据5 d% d& m" T; p7 A% x
  34. void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)1 Q) q# R, j8 y$ R
  35. {+ o& X& g1 t( S" j( r
  36.     W25QXX_Write_Enable();                  //写使能
    / j7 Y$ U& S& H! W; h0 s
  37.         W25QXX_CS(0);                            //使能器件   
    : h1 {, }# V) R0 |
  38.     W25QXX_ReadWriteByte(0x12);                           //发送4字节地址页写命令   
    & X0 |& @. R" m1 E: q) ]
  39.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>24));//发送32bit地址
    ' W" Y& Y* u+ V* g
  40.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>16));    / p3 e0 U3 m2 p& [) y. ^4 I
  41.     W25QXX_ReadWriteByte((uint8_t)((WriteAddr)>>8));   
    # |  p. _- Q" c: }3 ]! c& q
  42.     W25QXX_ReadWriteByte((uint8_t)WriteAddr);   
    7 H5 h$ F: P7 k
  43.     for(uint16_t i=0;i<NumByteToWrite;i++)//可写多个数据,最多256个字节一页数据) S1 x8 o; P' {; s
  44.         {
    # S  U/ X8 j6 Y  l  S  X
  45.                 W25QXX_ReadWriteByte(pBuffer);//循环写数  
    / x: I* s) B. @, M
  46.         }: A0 P  K. q7 j; b4 H3 U. {- W
  47.         W25QXX_CS(1);                                    //取消片选 , u4 x) g" n4 }3 o& ?
  48.         W25QXX_Wait_Busy();                                                           //等待写入结束' p5 |) q, j, K9 O. r, u! y) @
  49. }
复制代码

# B1 o3 C0 |  e" o注:如果想要实现4字节地址,需要启用4字节地址模式。) U- E( {+ }5 ~6 D6 q- j

  ~. R  N  O) p  R操作命令 如下表所示:
9 t: |5 f2 x( F: x" J
8 n% D9 f+ P2 y5 A  T& R7 V
& g; c9 p9 `8 f& J' [! M3 x. c3 L! X) O  A
————————————————
: k; I+ J4 ]& J0 B* P! G版权声明:根号五5 `3 ]& n( E1 Q  O/ z1 P7 A
- v! X0 s) W+ g3 D  Y. J; q# M
1 z/ Y  H; |; i/ S" z+ A
' b$ G* k( z% {1 n2 v' X
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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版