STM32H7驱动W25QXX

STM32的QSPI测试

    • ==测试环境数据==
  • 文档翻译
    • 引脚摘要
    • 结构图
    • 功能描述
      • ==SPI和QSPI操作==
      • 状态寄存器
      • 指令
      • 时序图
      • == 开始我们的代码编写==
          • 实验一读取ID:
            • 定义一些常用的指令
            • 发送指令
            • 接收数据/发送数据
            • 实践
          • 实验二读取状态寄存器的值
            • 读取指定寄存器值
            • 实验测试及结果
          • 实验三读取指定地址数据
            • 阻塞等待
            • 读取指定地址数据
            • 测试及结果
          • 实验四传输写指令
            • 使能写/禁止写
            • 测试及结果
          • 实验五擦除扇区
            • 擦除扇区
            • 测试及结果

测试环境数据

测试对象:H743Vit6
频率:
AXI:200MHz
QUSPI :200MHz
分频系数:5
FIFO:4
是否延迟:半个周期
内存大小:22
CS延迟:4周期
clock:模式0
单片ID1

文档翻译

引脚摘要

CS
芯片选择
高电平:设备取消选择,输出数据线-高阻态
下降沿:指令可以写入到设备并从设备读取数据
接收新指令:/cs必须从高到低过度
串行数据输入、输出IO1-3
W25Q64FV支持标准SPI、双SPL、Quad SPL和QPL操作。
标准SPI指令使用单向输入引脚将指令、地址或数据串行写入,在串行时钟(CLK)输入引脚上升边缘上的设备。标准SPI还使用单向DO(输出)从CLK下降边缘的设备读取数据或状态。

DUAL/Quad SPL和QPI指令使用双向LO引脚将指令、地址或数据串行写入CLK上升边缘上的设备,并从CLK的下降沿读取设备的数据或状态。Quad SPL和QPI指令要求设置SR2寄存器中的非易失性四位启用位(QE)。当QE=1时,/WP引脚变成IO2,/HOLD变成lO3。
写保护
用于防止状态寄存器被写入。与状态寄存器的块保护(CMP、SEC、TB、BP2、BP1、和BP0)位和状态寄存器(SBR)结合使用,部分小于4KB的扇区或整个内存阵列可以被硬件保护。
/WP引脚活动在低电平
参见图ia、1b和1c,用于Quad l/O操作的引脚配置。

当此引脚作为IO2时,将无法使用/WP引脚功能
保持
当/cs引脚拉低时,Do将处于高阻态,DI和CLK引脚上信号将被忽略。
当状态寄存器-2的QE位被设置为Quad Lo时,由于此引脚用于lO3,因此无法使用/持有引脚函数。
高电平:设备操作回复
CLK
SPI串行时钟Ilnput(CL.K)引脚提供串行输入和输出操作的时间。

结构图

STM32H7驱动W25QXX_第1张图片
内部有256字节的页缓冲区

功能描述

SPI和QSPI操作

STM32H7驱动W25QXX_第2张图片
标准SPI操作
使用标准的SPI总线访问(包括:CLK、/CS、DI、DO)
标准SPI在CLK上升沿使用DI来发送指令、地址或数据发送到设备,读取则是通过DO在CLK下降沿上收数据。
支持SPI的0、3操作模式;区别在与待机CLK的状态,都是下降沿采样。STM32H7驱动W25QXX_第3张图片双线SPI
在使用-
快速读取双输出指令----3BH
快速读取双I/O ----BBH
等指令时,支持双线SPI模式。这将允许数据通过2-3倍的速率送到设备或从设备传出。
使用双线SPI时,DI/DO将变成双向I/O口:IO0和IO1
四线SPI
在使用-
快速读取且四线输出 ----6BH
快读读取四路IO ----EBH
字节读取四路IO ----E7H
八进制字节读取IO ----E3H
当使用四位SPL指令时,DI和DO引脚分别变成双向的IO0、IO1,WP和/HOLD引脚分别变成IO2和IO3
四位SPI指令要求在状态寄存器-2中设置非易失性四位启用位(QE)。
QPI操作
W25Q64要想支持四线外围接口(QPI)接口,只有当设备使用“ENABLE QPI(38H)”从标准/双/四线SPI切换到QPI。

典型的SPI协议要求字节长的指令只能通过DI引脚在8个CLK时钟移位到设备中。
QPI模式利用四个IO引脚来输入指令,因此只需要2个串口时钟。
这样可以显著减少SPI的指令消耗,并提高XIP环境中的系统性能。
标准/双/四线SPI和QPI模式是分开的,在给定的时间内,只有一种模式是激活的。
在上电/使用“rest 99H”指令进行软件复位后,设备的默认状态位标准/双/四线SPI
为了启用QPI模式,需要设置SR2中非易失性QE位为1,使用QPI指令时,DI和D0变成双向IO口,而且WP和HOLD也变成了双向IO口。
保持
对于标准/双线SPI,当主动选择W25Q64时(/cs为低),/HOLD允许W25Q64暂停操作,在SPI数据和时钟信号与其他设备共享的情况下,/HOLD功能可能很有用。例如,考虑当优先级中断需要使用SPI总线时,页面缓冲区是否只被部分写入。在这种情况下,/HOLD函数可以在缓冲区中保存指令和数据的状态,这样,一旦总线再次可用,编程就可以恢复到中断状态。该/HOLD函数仅适用于标准SPI和双线 SPI操作,而不适用于四线 SPL或QPI。
要启动/保持条件,必须选择/CS低的设备。如果CLK信号已经很低,A/Holding条件将激活/保持信号的下降边缘。如果CLK尚未降低,则在CLK的下一个下降边缘之后将激活/保持条件。如果CLK信号已经很低,/Holding条件将在/Holding信号的热边缘终止。如果CLK尚未降低,则/HOLD条件将在CLK的下一个下降边缘后终止。在lHOLD状态下,串行数据输出(D0)是高阻抗的,忽略了串行数据输入(DL)和串行时钟(CLK),芯片选择(/cs)信号应在整个保持操作期间保持活动(低),以避免重新设置设备的内部逻辑状态。
写保护
使用非易失性内存的应用程序必须考虑到噪音和其他可能损害数据完整性的不利系统条件的可能性。为了解决这一问题,W25064FV提供了几种保护数据免遭意外写入的方法。

1.使用状态寄存器编写启用/禁用指令和自动写入禁用后擦除或编程软件和硬件(WP引脚)写入保护
2.用断电指令写保护
3.锁定状态寄存器的写入保护,直到下一次停电。
4.一次程序(OTP)使用状态寄存器为数组和安全寄存器编写保护

注意:
在上电或断电时,W25Q64FV将保持复位状态,而VCC低于大众的阈值(请参阅电源上升定时和电压电平及图43)。当重置时,所有操作都被禁用,没有任何指令被识别。在供电期间和VCC电压超过VW后,所有程序和擦除相关指令都被进一步禁用,以延迟tPuw。这些指令包括写启用、页程序、扇区擦除、块擦除、芯片擦除和写入状态寄存器指令。请注意,芯片选择引脚(/CS)必须跟踪VCC电源电平,直到达到vcc-min级和tvsL时间延迟,并且还必须跟踪VCC电源级以防止出现不利的命令序列。如果需要,可以使用拔起电阻on/cs来完成这一任务。
在打开电源后,devlce被自动置于状态寄存器写入程序(WEL)设置为0的禁用写入状态,在页面程序、SectorErase、块擦除、芯片擦除或写入状态寄存器指令被接受之前,必须发出写启用指令。在完成一个程序后,擦除或写指令写使能舱口(WEL)自动被清除到写禁用状态为0。

使用写入状态寄存器指令和设置状态寄存器保护(SRPO、SRP 1)和块保护(CMP、SEC、TB、BP 2、BP 1和BP0),软件控制的写保护得到了便利。这些设置允许只对4KB扇区或整个内存数组进行配置。与写保护(WP)引脚一起使用,状态寄存器的更改可以在硬件控制下启用或禁用。更多信息请参见状态寄存器部分,另外,除了发布的下传指令之外,所有指令都会被忽略,因此电源下降指令提供了额外的写保护级别。

状态寄存器

“读状态寄存器-1”和“状态寄存器-2”指令可用于提供闪存阵列可用性的状态,如果设备已启用或禁用写入功能,则可提供写入保护状态、四SPL设置、安全寄存器锁定状态和擦除/程序挂起状态。WriteStatus寄存器指令可用于配置设备写保护功能、Quad SPL设置和安全寄存器OTP锁。对状态寄存器的访问由非易失性状态寄存器保护位(SRP 0、SRP 1)、写入启用指令以及在标准/双SPL操作期间的/WP引脚控制。
忙-BUSY
繁忙是状态寄存器1(S0)中的只读位,当设备执行APAGE程序、四页程序、扇区擦除、块擦除、芯片擦除、写入状态寄存器或Erase/程序安全寄存器指令时,**该位位设置为1状态。**在此期间,设备将忽略进一步的指令–除了读状态寄存器和擦除/程序挂起指令(参见tw、TPP、TSE、TBE和tcE中的AC特性)。当程序、擦除或写入状态安全寄存器指令完成后,繁忙位将被清除到0状态,表明设备已准备好接受进一步的指令。
写使能-WEL
写使能时状态寄存器的(S1),它是只读的,在执行写使能指令后硬件设置为1,当设备处于写禁止的时候会自动清0.
执行这些指令引发写使能状态清0:写禁用、块擦除、页程序、四页程序、扇区擦除、块擦除、芯片擦除、写入寄存器、清除Security寄存器和程序安全寄存器
块保护(BP2、BP1、BP0)
(BP2、BP1、BP0)也就是(S4、S3、S2)是块保护位,他们都是非易失性的读/写位。
块保护可以用来使用“Write Status Register”指令来设置,
所有内存数组的任何或一部分都不能被程序和擦除指令保护(参见状态寄存器内存保护表)。块保护位的工厂默认设置为0,没有任何数组受保护。
==顶部/底部块保护(TB) ==
非易失性顶部/底部位(TB) 控制块保护位(BP2、BP1、BP0)是否从数组的顶部(TB=0)或底部(TB=1)保护,
如状态寄存器内存保护表中所示。
工厂默认设置为TB=0。TB位可以根据SRPO、SRP 1和WEL位的状态使用写状态寄存器结构来设置
扇区/块 保护(SEC)
非易失性扇区/块保护位(SEC)控制如果块保护位(BP2、BP1、BPO),保护4KB扇区(SEC=1)或64 KB块(SEC=0),则控制数组的顶部(TB=0)或底部(TB=1),如状态寄存器内存保护表所示。默认设置为SEC=0
complement保护(CMP)
补保护位(CMP)是状态寄存器(S14)中的非易失性读/写位。它与SEC、TB、BP2、BP 1和BP 0位结合使用,为数组保护提供了更大的灵活性。OnceCMP设置为1,以前由SEC、TB、BP2、BP 1和BP 0设置的数组保护将被恢复。例如,当CMP=0时,可以保护顶级4KB扇区,而其余数组则不受保护;当CMP=1时,顶部4KB扇区将不受保护,而数组的其余部分只会被读取–只需阅读。请访问状态寄存器内存保护表以获取详细信息。默认设置为CMP=0
状态寄存器保护(SRP1、SRP0)
状态寄存器保护位(SRP 1和SRPO)是状态寄存器(S8和S7)中的非易失性读/写位。SRP位控制写保护的方法:软件保护、硬件保护、电源锁定或一次可编程(OTP)保护。
STM32H7驱动W25QXX_第4张图片
擦除/程序挂起 状态(SUS)
挂起状态位是状态寄存器(S15)中的只读位,在执行Erase/progran suspend(75h)指令后被设置为1。SUS状态位通过擦除/程序恢复(7AH)指令以及一个断电向上循环被清除为0
安全寄存器所(LB3,LB2,LB1)
(lb3、lb2、lB1)是状态寄存器(S13、S12、S11)中的非易失一时间程序(OTP)位,为安全寄存器提供写保护控制和状态。Lb3-0的默认状态是0,安全寄存器被解锁。LB3-1可以使用WITE状态寄存器指令单独设置为1。LB3-1是一次可编程的(OTP),一旦设置为1时,响应256-Byte安全寄存器将变成永久只读。
使能QE(QE)
是状态寄存器中非易失性状态位S9,他是读写位,允许QSPI和QPI操作。
置0:启用/WP、/HOLD
置1:启用quad的IO2、IO3,禁用/WP、/HOLD

若启用QPI模式则还将发出指令"EnableQPI(38H)",此时将从“标准/双线/四线SPI”切换到“QSPI”模式

注意:
在“QPI”模式下,是不支持将QE置为0的

警告:
果/WP或lHOLD引脚在标准SPL或双SPL操作中直接绑定到电源或地面,则QE位不应设置为1。

STM32H7驱动W25QXX_第5张图片STM32H7驱动W25QXX_第6张图片
STM32H7驱动W25QXX_第7张图片

指令

W25Q64的标准/双线/四线SPI指令集有36个基本指令集组成,他们通过SPI总线完全控制,指令由芯片的/cs下降沿发出,在时钟上升沿对DL输入的数据采样,得到MSB
W25Q63的QPI指令有24条基本指令组成,他们通过SPI总线完全控制,指令从/cs的下降沿发出,通过IO[3:0]引脚锁定的第一个字节提供了字节码,所有的数据应该时钟的上升沿取样,首先具有最重要的MSB位,所有的QPI指令、地址、数据和虚拟字节使用所有的IO引脚在两个时钟传输每个字节。
指令的长度从一个字节到几个字节不等,后面可能是地址字节、数据库、虚拟字节(不关心),在某些情况下,还有组合。指令是用边缘/CS的边缘完成的。图5至图42中包含了每条指令的时钟相对时序图。所有读取指令都可以在任何时钟位之后完成。但是,所有的指令都必须在字节边界上完成(在一个完整的8位后驱动到很高的位置),否则指令就会被忽略,这一特性进一步保护了设备不被无意写入。此外,在对内存进行编程或删除时,或者在写入状态寄存器时,除读状态寄存器之外的所有指令都将被忽略,直到程序或擦除生命周期完成为止。

制造商和设备鉴定
STM32H7驱动W25QXX_第8张图片
标准SPI指令:
STM32H7驱动W25QXX_第9张图片
双线SPI
STM32H7驱动W25QXX_第10张图片
四线SPI
STM32H7驱动W25QXX_第11张图片

STM32H7驱动W25QXX_第12张图片
注意:
1.首先用最重要的位移位数据字节。括号中有数据的字节字段“()”表示设备在1、2或4个LO引脚上的数据输出
2.状态寄存器内容和设备LD将连续重复,直到/cs终止指令。
3.状态寄存器内容和设备LD将连续重复,直到/cs终止指令。寻址将包装到页面的开头,并覆盖以前发送的数据。
4.有关设备LD信息,请参见制造商和设备识别表。
5.安全寄存器地址:
在这里插入图片描述
6.双线SPI地址输入格式
在这里插入图片描述
7.双线SPI数据输出格式
在这里插入图片描述
8.四线SPI的地址输入模式
STM32H7驱动W25QXX_第13张图片
STM32H7驱动W25QXX_第14张图片
9.四线SPI数据输入/输出格式
STM32H7驱动W25QXX_第15张图片
10.四线I/O的快速读取数据输出格式:
STM32H7驱动W25QXX_第16张图片
11.四线I/O读字数据输出格式:
STM32H7驱动W25QXX_第17张图片
12.四路IO读取字节,最低地址位必须是0。(ao=O)
13.四路IO读取八进制字,最低的四个地址位必须是0。(A3,A2,A1,AO=0)
14.QPI命令、地址、数据输入/输出格式:
STM32H7驱动W25QXX_第18张图片
15.QPI的快速读、快速四线读、页读的空周期有读取参数P7-P4控制
16.带wrap的QPl突发读的缠绕长度由读参数P3-P0控制。

时序图

写使能(06H)

该指令将会导致状态寄存器中(WEL)位置为1.
该指令必须在页面程序、四页程序、扇区擦除、块擦除、芯片擦除、写入状态寄存器和擦除程序安全寄存器之前设置。
该寄存器通过/cs拉低来输入,将06H在clk的上升沿驱动到DL引脚中,然后将/cs拉高。
STM32H7驱动W25QXX_第19张图片
对易失性寄存器的写使能(50H)
在前面已经描述了非易失性状态寄存器也可以被视为易失性位,这将提供了更多的灵活性,以改变系统的配置,和内存保护方案,迅速与向外典型的非易失性比特写入循环或影响状态寄存器的持久性,非易失性比特。若要将易失性值写入状态寄存器位,必须在写入状态寄存器(01h)指令之前发出对Volatle状态寄存器(50h)指令的写启用功能。写入EnableforVolativeStatus寄存器指令(图6)不会设置写启用Latch(WEL)位,它只对写状态寄存器指令有效地更改易失性状态寄存器位值。
STM32H7驱动W25QXX_第20张图片
写禁用

写禁用指令(图7)将状态寄存器中的写启用Latch(WEL)位重置为0。写禁用指令通过驱动/CS低输入,将指令代码“O4h”移到Dl引脚,然后驱动/CS高。请注意,WEL位是在写状态寄存器、擦除/程序安全寄存器、页面程序、Quad页面程序、扇区擦除、块擦除、芯片擦除和复位指令完成后自动复位的。
STM32H7驱动W25QXX_第21张图片
读状态寄存器1(05H)或2(35H)
该指令是通过驱动/cs变低,并将指令码(05H)或状态寄存器2(35H)在clk的上升沿移入到DI来输入的
然后状态寄存器位在clk下降沿移出到DO引脚,其中最有效位MSB优先
STM32H7驱动W25QXX_第22张图片
STM32H7驱动W25QXX_第23张图片
状态寄存器的写(01H)
该指令允许写状态寄存器
1支持:SRPO、SEC、TB、BP2、BP1、BPO
2支持:CMP、LB3、LB2、LBi、QE、SRP1
所有其他状态寄存器都是只是只读的,不会受到写状态寄存器的影响
LB3-0为非易失性OTP位,设置为1后不能清除为0。

写之前应先输入使能写指令(06H),让WEL状态位置1,再传入写状态寄存器指令(01H)

要写易失性状态寄存器位时,必须再使能写指令前执行一个写易失性状态位指令(50H)但是,SRP1和LB3,LB2, LB1由于OTP保护,不能从“1”更改为“0”。

在断电或执行“Reset (99h)”指令时,易失性状态寄存器位值将丢失,而非易失性状态寄存器位值将被恢复。

为了完成写状态寄存器指令,/CS引脚必须在第8位或第16位数据被锁定后被驱动。

如果不这样做,写状态寄存器指令将不会被执行。

在第八个时钟(与25X系列兼容)后,lf /CS被驱动高,CMP,QE和srp1位将被清除到o。

在非易失性状态寄存器写操作(06h和01h结合),在/CS驱动高后,自定时写状态寄存器周期将开始tw的持续时间(见AC特性)。当写状态寄存器循环正在进行时,读状态寄存器指令仍然可以被访问,当循环结束并准备再次接受其他指令时,一个0。在Write StatusRegister周期完成后,状态寄存器中的Write Enable Latch(WEL)位将被清除为0。
检查忙位状态。在写状态寄存器周期中,忙碌位是1

在易失性状态寄存器写操作(50h + 01h)中,在/CS驱动高后,状态寄存器位将在tsHsL2时间内刷新到新的值(见ACCharacteristics)。在状态寄存器位刷新期间,忙碌位将保持0。

写状态寄存器指令可以在SPl模式和QPl模式下使用。但是,当设备处于QPl模式时,不能写入QE位,因为设备进入并在QPl模式下操作需要QE=1。

详细的状态寄存器位描述请参见7.1。所有状态寄存器的出厂默认值都是0。

STM32H7驱动W25QXX_第24张图片

读数据(03H)
地址宽度:24位
允许从内存中顺序的读取一个多个数据字节。该指令在/cs拉低后,每步再clk的上升沿中,然后移动指令(03H),再移动地址(A24-A0)到DI引脚。
地址被接收后,寻址寄存器位置的数据将再clk下降沿持续将数据唱移出。在每个数据移出后,地址会自动增加到下一个高地址,从而允许一个连续的数据流
这意味着一条指令将能访问整个内存。

如果在erase、Program或Write cycle (BUSY=1)进程中发出读数据指令,该指令将被忽略,不会对当前周期产生任何影响。
STM32H7驱动W25QXX_第25张图片
快速读(0BH)
与读取数据指令相似,但不同于可以工作在最高的FR频率
这是通过在图11所示的24位地址之后添加8个“空”时钟来完成的。
在空时钟期间,DO引脚上的数据值是“无效的”。
STM32H7驱动W25QXX_第26张图片
QPI中快速度(0BH)
快速读取在QPI模式中也将得到支持
当QPI模式启用时,空时钟的数量由"Set Read Parameters (COh)"指令来设置,不同的需求可以最大快速读取频率或最小数据访问延迟。根据阅读参数比特P[5:4]设置,假时钟的数量可以决定为2、4、6或8个。

在恢复或恢复后,空时钟的默认数量为2。
双线输出的快速度(3BH)
快速读双输出(3Bh)指令与标准快速读(0Bh)指令相似,除了数据输出在两个引脚上;lO和lO1。这允许数据以标准SPl设备两倍的速度从W25Q64FV传输。快速读双输出指令是理想的快速下载代码从闪存到RAM上的电源或应用程序,缓存代码段,以便执行。
STM32H7驱动W25QXX_第27张图片
四路输出的快速读
快速读四路输出(6Bh)指令类似于快速读双路输出(3Bh)指令,除了数据输出在四个引脚上,lIOo,IO1, IO2,和lOga。状态寄存器-2的四元使能必须在设备将接受快速读四元输出指令之前被执行(状态寄存器位q必须等于1)。快速读四元输出指令允许数据从W25Q64FVat标准SPl设备的四倍速率被传输。
快速读四次输出指令可以在FR的最高频率下工作(见ACElectrical Characteristics)。这是通过在图13所示的24位地址之后添加8个“虚拟”时钟来完成的。假时钟允许设备的内部电路有额外的时间来设置初始地址。在假时钟期间的输入数据是“不在乎”。然而,在第一个数据输出时钟的下降边缘之前,lO引脚应该是高阻抗的。
STM32H7驱动W25QXX_第28张图片
快速读 四路I/O(EBH)
快速读四路IVO (EBh)指令类似于快速读双路I/O (BBh)指令,除了地址和数据位是通过四个引脚lO0、IO、lO和lO输入和输出;在输出数据之前,SPl模式需要四个假时钟。Quad i/0极大地减少了指令开销,允许直接从Quad SPI更快地随机访问代码执行(XIP)。状态寄存器-2的四能位(QE)必须设置为使能快速读四能存取指令。
快速读四倍IO与“连续读模式”
快速读四次指令IO可以通过在输入地址位(A23-0)之后设置“连续读模式”位(M7-0)来进一步减少指令开销,如图15a所示。(M7-4)的上小块通过包含或排除第一个字节指令代码来控制下一个快速读四字节l0指令的长度。(M3-0)的下部是不关心(“×”)。然而,l0引脚在第一个数据输出时钟的下降边缘之前应该是高阻抗的。
如果“连续读模式”位M5-4 =(1,0),则下一个快速读四次l/O指令(ICSis先升后降之后)不需要EBh指令代码,如图15b所示。这将指令序列减少8个时钟,并允许在/CS断言为低时立即进入读地址。如果连续读模式的“位M5-4不等于(1,0),下一条指令(在/CS之后上升然后下降)需要第一个字节指令代码,因此返回正常操作。建议下一条指令(8个时钟)在l00上输入FFh,确保M4= 1,使设备恢复正常运行。
STM32H7驱动W25QXX_第29张图片
STM32H7驱动W25QXX_第30张图片
在标准的SPl模式下,快速读取四字节lO与“8/16/32/64字节绕”
快速读四次l/0指令也可以通过在EBh之前发出“Set Burst with Wrap”(77h)命令来访问页面中的特定部分。“Set Burst with Wrap”(77h)命令可以为以下EBh命令启用或禁用“Wrap Around”功能。当启用“WrapAround”时,被访问的数据可以被限制在256字节页面的8、16、32或64字节部分。输出数据从指令中指定的初始地址开始,一旦它到达8/16/32/64字节部分的结束边界,输出将自动绕到开始边界,直到/Cs被拉高以终止命令。
Burst with Wrap特性允许使用缓存的应用程序快速获取一个关键地址,然后在固定长度(8/16/32/64字节)的数据之后,不需要发出多个readcommand。
" Set Burst with Wrap "指令允许设置三个"Wrap "位,即W6-4位。W4位用于启用或禁用"Wrap Around "操作,而W6-5位用于指定页内Wrap部分的长度。详细说明请参见7.2.19。

快速读4倍IO(EBH)
QPl模式也支持快速读四次l/O指令,如图15c所示。当QPImode被启用时,虚拟时钟的数量由“Set Read Parameters (Coh)”指令来配置,以适应各种不同的应用程序,这些应用程序需要最大快速读频或最小数据访问延迟。根据读取参数比特P[5:4]的设置,虚拟时钟的数量可以配置为2、4、6或8。默认clocksupon上电或复位指令后的哑时钟数为2。在QPl模式下,“连续读模式”位M7-0也被认为是哑时钟。在默认设置中,数据输出将立即跟随连续ReadMode位。
“连续读模式”功能也可在QPl模式快速读四l/O指令。请参考前几页的描述。
**在QPl模式中,快速读四倍lO指令的“连续读”功能不可用。要在QPl模式下执行具有固定数据长度的绕读操作,必须使用专用的“带绕读的Burst Read”(0Ch)指令。**详情请参阅7.2.39。
STM32H7驱动W25QXX_第31张图片

== 开始我们的代码编写==

实验一读取ID:
定义一些常用的指令
#define ManufactDeviceID_CMD    0x90
#define READ_STATU_REGISTER_1   0x05
#define READ_STATU_REGISTER_2   0x35
#define READ_DATA_CMD            0x03
#define WRITE_ENABLE_CMD        0x06
#define WRITE_DISABLE_CMD        0x04
#define SECTOR_ERASE_CMD        0x20
#define CHIP_ERASE_CMD            0xc7
#define PAGE_PROGRAM_CMD        0x02
发送指令
HAL_StatusTypeDef QSPI_Send_Command(uint32_t instruction, 
                                    uint32_t address, 
                                    uint32_t dummyCycles, 
                                    uint32_t instructionMode, 
                                    uint32_t addressMode, 
                                    uint32_t addressSize, 
                                    uint32_t dataMode)
{
    QSPI_CommandTypeDef cmd;

    cmd.Instruction = instruction;                     //指令
    cmd.Address = address;                          //地址
    cmd.DummyCycles = dummyCycles;                  //设置空指令周期数
    cmd.InstructionMode = instructionMode;            //指令模式
    cmd.AddressMode = addressMode;                   //地址模式
    cmd.AddressSize = addressSize;                   //地址长度
    cmd.DataMode = dataMode;                         //数据模式
    cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;           //每次都发送指令
    cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节
    cmd.DdrMode = QSPI_DDR_MODE_DISABLE;               //关闭DDR模式
    cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;

    return HAL_QSPI_Command(&hqspi, &cmd, 5000);
}
接收数据/发送数据
//-----------------------------发送-----------------
HAL_StatusTypeDef QSPI_Transmit(uint8_t* send_buf, uint32_t size)
{
    hqspi.Instance->DLR = size - 1;                         //配置数据长度
    return HAL_QSPI_Transmit(&hqspi, send_buf, 5000);        //接收数据
}
//-----------------------------接收-----------------
HAL_StatusTypeDef QSPI_Receive(uint8_t* recv_buf, uint32_t size)
{
    hqspi.Instance->DLR = size - 1;                       //配置数据长度
    return HAL_QSPI_Receive(&hqspi, recv_buf, 5000);            //接收数据
}
实践
printf("\n\n---------------------start---------------------------\n");
printf("ID:%04X\n",W25QXX_ReadID());

在这里插入图片描述

实验二读取状态寄存器的值
读取指定寄存器值
uint8_t W25QXX_ReadSR(uint8_t reg)
{
    uint8_t cmd = 0, result = 0;    
    switch(reg)
    {
        case 1:
            /* 读取状态寄存器1的值 */
            cmd = READ_STATU_REGISTER_1;
        case 2:
            cmd = READ_STATU_REGISTER_2;
        case 0:
        default:
            cmd = READ_STATU_REGISTER_1;
    }
    QSPI_Send_Command(cmd, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_24_BITS, QSPI_DATA_1_LINE);
    QSPI_Receive(&result, 1);

    return result;
}
实验测试及结果

运行

printf("\n\n---------------------start---------------------------\n");
printf("ID:%04X\n",W25QXX_ReadID());
printf("SR1:%2x\n",W25QXX_ReadSR(1));
printf("SR2:%2x\n",W25QXX_ReadSR(2));

STM32H7驱动W25QXX_第32张图片

实验三读取指定地址数据
阻塞等待
void W25QXX_Wait_Busy(void)
{
    while((W25QXX_ReadSR(1) & 0x01) == 0x01); // 等待BUSY位清空
}
读取指定地址数据
void W25QXX_Read(uint8_t* dat_buffer, uint32_t start_read_addr, uint16_t byte_to_read)
{
    QSPI_Send_Command(READ_DATA_CMD, start_read_addr, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_1_LINE, QSPI_ADDRESS_24_BITS, QSPI_DATA_1_LINE);
    QSPI_Receive(dat_buffer, byte_to_read);
}
测试及结果
uint8_t w25read_buf[20]={0};




printf("\n\n---------------------start---------------------------\n");
printf("ID:%04X\n",W25QXX_ReadID());
printf("SR1:%2x\n",W25QXX_ReadSR(1));
printf("SR2:%2x\n",W25QXX_ReadSR(2));
W25QXX_Read(w25read_buf,100,20);
printf("data:%20x\n",w25read_buf);

STM32H7驱动W25QXX_第33张图片

实验四传输写指令
使能写/禁止写
//----------------------使能写
void W25QXX_Write_Enable(void)
{
    QSPI_Send_Command(WRITE_ENABLE_CMD, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE);
        W25QXX_Wait_Busy();
}
//----------------------禁止写
void W25QXX_Write_Disable(void)
{
    QSPI_Send_Command(WRITE_DISABLE_CMD, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE);
        W25QXX_Wait_Busy();
}
测试及结果

翻车了,这个不要乱测试。。。。。。

实验五擦除扇区
擦除扇区
void W25QXX_Erase_Sector(uint32_t sector_addr)
{
    sector_addr *= 4096;    //每个块有16个扇区,每个扇区的大小是4KB,需要换算为实际地址
    W25QXX_Write_Enable();  //擦除操作即写入0xFF,需要开启写使能
    W25QXX_Wait_Busy();        //等待写使能完成
    QSPI_Send_Command(SECTOR_ERASE_CMD, sector_addr, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_1_LINE, QSPI_ADDRESS_24_BITS, QSPI_DATA_NONE);
    W25QXX_Wait_Busy();       //等待扇区擦除完成
}
测试及结果
printf("\n\n---------------------start---------------------------\n");
printf("ID:%04X\n",W25QXX_ReadID());
printf("SR1:%2x\n",W25QXX_ReadSR(1));
printf("SR2:%2x\n",W25QXX_ReadSR(2));

W25QXX_Read(w25read_buf,100,20);
printf("data:%20x\n",w25read_buf);

printf("W25XX_Write_Enable....\n");
//W25QXX_Write_Enable();
printf("ID:%04X\n",W25QXX_ReadID());
printf("SR1:%2x\n",W25QXX_ReadSR(1));
printf("SR2:%2x\n",W25QXX_ReadSR(2));
printf("W25XX_Write_Disable....\n");
//W25QXX_Write_Disable();
printf("ID:%04X\n",W25QXX_ReadID());
printf("SR1:%2x\n",W25QXX_ReadSR(1));
printf("SR2:%2x\n",W25QXX_ReadSR(2));

W25QXX_Read(read_buf, 5, 11);
printf("read date from addr 5 is :%s\r\n", (char*)read_buf);
printf("Erase_this_Sector ,addr is :5/4096...\n");
W25QXX_Erase_Sector(5/4096);
W25QXX_Wait_Busy();
W25QXX_Read(read_buf, 5, 11);
printf("read date from addr 5 is :%s\r\n", (char*)read_buf);

STM32H7驱动W25QXX_第34张图片

你可能感兴趣的:(STM32,W25Q64,W25Q128,QSPI)