手把手系列--STM32 QSPI操作指南

2023-11-23 10:59

本文主要是介绍手把手系列--STM32 QSPI操作指南,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本主题相关内容

手把手系列--华邦W25Q64JV Flash操作指南_coder.mark的博客-CSDN博客_w25q64手册https://blog.csdn.net/tianizimark/article/details/121712792手把手系列--华邦W25Q128JV Flash操作指南_coder.mark的博客-CSDN博客_w25q128jvhttps://blog.csdn.net/tianizimark/article/details/121717803理解SPI/Dual SPI/Quad SPI/QPI之间的区别_coder.mark的博客-CSDN博客https://blog.csdn.net/tianizimark/article/details/124608851

一、目的

        前段时间淘了一块STM32H750XBH6_ArtPi开发板,板载两颗华邦的Flash芯片,一颗为W25Q64JV(8Mbytes),通过STM32H750XBH6的QUADSPI控制用于XIP;一颗为W25Q128JV(16Mbytes)用于数据存储。

        然后W25Q64JV使用Quad SPI方式连接,W25Q128JV使用标准SPI连接。

        本博文基于此开发板从基础给大家介绍一下STM32 Quad SPI的功能。

        按照惯例,我们从官网找到如下资料。

        参考ST官方Quad SPI使用文档

        

                        Quad-SPI接口一般用于数据存储或者用于代码执行。

                另外官网还有一个特别好的中文资料

              

二、介绍

        QUADSPI系统框图

        STM32系列芯片上的Quad-SPI允许主机和外部Quad-SPI存储设备之间进行四根数据线通信;其支持传统的SPI也支持双线模式;Quad-SPI使用最多6根线。

         

                 我们开发板上的芯片为STM32H750XBH6,其Quad-SPI支持的SDR(单时钟速率下)最大时钟频率为133MHz, DDR(双时钟速率下)为100MHz;硬件FIFO最大32字节,支持双Flash,即BINK1和BINK2,并且这两个BANK可以级联组成一个8线的外部存储;内存映射模式下最大支持256Mbytes的大小,间接模式下支持4Gbytes空间。

        

        在内存映射模式下,Quad-SPI接口被映射到AHB总线上,也就是说AHB总线可以直接读取数据(即通过指针直接读取)。

         

                 Quad-SPI接口提供了一个完全可配置的帧格式,最大包含五个阶段并且每个阶段都可以完全配置(也就是说每个阶段的数据长度和数据线数完全可以独立配置)。

                从上图我们可以看到这五个阶段分别为指令阶段、地址阶段、交替(可选)字节阶段、空指令阶段、数据阶段。一般情况下都是会有指令阶段。进行数据读写时一般包括指令、地址、数据阶段l;特殊情况下尤其是高速数据读写时需要设置空指令周期(和外部Flash芯片强相关)。

        指令阶段

        

                 指令阶段只可以发送一个字节的数据,通过往寄存器QUADSPI_CCR[7:0]的INSTRUCTION字段写入即可。指令可以通过1/2/4线发送。一般1线的比较常见。

        

               IMODE[1:0]=00代表没有指令阶段。

             

        地址阶段

         地址阶段可以发送1/2/3/4个字节,写入QUADSPI_AR寄存器即可;可以通过1/2/4线发送,通过ADSIZE指定地址字节长度,通过ADMODE指定是否有地址/1线/2线/4线模式。

     

           交替字节阶段

 

         通过ABSIZE指定发送的1/2/3/4字节,通过ABMODE指定是否有交替字节、1/2/4线发送。选项字节写入QUADSPI_ABR寄存器。

        空指令阶段

        

                         空指令周期用于高速通信的场景中,用于确保数据信号从输出模式转变为输入模式。

                        通过DCYC[4:0]最大可以设置31个周期。

                        注意:如果使用了QUADSPI硬件配置并且此周期内使用Quad-SPI或者Dual-SPI模式,则IO2被硬件强制设置为0来金庸写保护功能并且IO被硬件强制设置为1来禁用保持功能。

        数据阶段

                 数据阶段可以配置读写任意字节的数据。通过QUADSPI_DLR设置数据长度,通过QUADSPI_DR寄存器读写数据;

                在内存映射模式下只能读取数据,其通过QUADSPI FIFO进行读取。总线矩阵上的任意主机都可以将其当作内部存储进行读取数据。

        

                数据阶段可以1/2/4线发送,也可以没有数据阶段。如果QUADSPI_DLR=0xFFFFFFFF,则数据传输直到字节数等于FSIZE。 

        硬件配置

                上图是标准SPI模式。注意IO0只能输出,IO1只能输入。

 

                上图是dual-SPI模式,注意注意IO0/IO1为双向通信。

                上图是Quad-SPI模式,注意注意IO0/IO1/IO2/IO3为双向通信。 

         双闪存模式

        

                双闪存模式下,指令、地址、交替字节、空指令周期同时发送给BINK1和BINK2。

        三种操作模式

        间接模式

                 间接模式用于读写、擦除操作;所有的操作都是通过QUADSPI数据寄存器来执行,可以使用CPU也可以使用中断和DMA;也用于配置Quad-SPI Flash内存。

                传输的数据通过数据寄存器和FIFO。

                自动轮询模式用于检测Flash内存中的状态寄存器的改变并产生中断,在检查擦除或者编程操作时特别有用(检查擦除或者编程是否完成)。

                状态标志轮询模式

                    用于读取Quad-SPI Flash内存的状态以及用于检测擦除或者编程的完成。开发者可以配置轮询周期以及轮询的掩码和匹配模式(与/或);当匹配发生时,自动产生中断并且停止。    

         内存映射模式

                用于读操作;将外部Quad-SPI Flash存储空间看作是内部空间,这样任何AHB主设备就可以自动读取;使用内存映射模式,QuadSPI自动管理预取机制,这可以优化外部Flash的读写执行性能 。

                

                内存映射模式下最大访问大小为256Mbytes,访问地址为0x90000000 - 0x9FFFFFFF;

                代码可以直接从外部Quad-SPI存储器里面执行。

        不支持直接从外部Quad-SPI Flash启动,但是可以先从内部Flash启动,然后配置QUADSPI为内存映射模式,然后就可以从外部Quad-SPI Flash执行代码。 

         

        上图是内存映射模式下建议的MPU设置为strongly-ordered类型,关于这个知识点请参考 

理解STM32上的MPU和Cache (一)_coder.mark的博客-CSDN博客_单片机mpuicon-default.png?t=M4ADhttps://blog.csdn.net/tianizimark/article/details/124698926

         中断描述

                 总共有5个中断,分别为超时、状态匹配(状态轮询模式时)、FIFO达到阈值(间接模式)、传输完成(间接模式下QUADSPI_DLR指定的字节数的数据已经发送完成)(所有模式下传输被终止)、传输错误(间接模式下地址越界);

                使用中断必须使能QUADSPI全局中断。

        DMA描述

                间接模式下可以DMA读写外部Quad-SPI Flash,内存映射模式下只支持读取。

                在DMA模式下,DMA负责过程控制。

                当QUADSPI FIFO达到阈值条件并且DMAEN位已经设置,则QUADSPI产生DMA请求到DMA控制器。

                如果DMAEN已经为1,如果需要更改FTHRES/FMODE则DMA控制器必须先禁用。

三、实战

        经过上面的讲解,大家应该对QUADSPI已经有了一个大致了解,下面我们通过代码工程来进一步加深理解。

        本篇我们只讲述CPU轮询方式控制,至于中断和DMA方式的实现,后面再给大家讲解。(要先给大家讲解一下移植FreeRTOS,不然中断或者DMA模式跟轮询的方式效果上没有大的差别)。

        下面我们来创建一个工程,为了简单我们还是使用STM32CubeMX生成一个Keil MDK工程

        参考《手把手系列--使用STM32CubeMX生成代码工程》

        为方便学习,这边提供的已经准备好的工程给大家下载

        链接:https://pan.baidu.com/s/1G_k7gXvPgc9O-sy3aqGBpw 
        提取码:r2fl

        工程中我们提供了W25Q64JV的驱动源码,下面我们根据源码一一讲解如何使用Quad-SPI。

        我们在Keil MDK工作下添加W25Q64JV分组用于存放其驱动代码。

         在主函数中我们做了如下操作

        

         初始化HAL,设置系统时钟,设置GPIO,设置QUADSPI,初始化并复位W25Q64JV;然后我们读取了一下W25Q64JV的ID,如果成功则先读取一下地址为0的4Kbytes的数据,然后我们进行写数据,再读取出来,通过调试模式,查看test_buf的数据是否跟我们代码设置的一样。

         关于W25Q64JV的描述请参考《手把手系列--华邦W25Q64JV Flash操作指南》。

        我们就以W25Q64JV的写使能命令为例说明

        

         首先我们先来看QSPI_CommandTypeDef这个结构体

        

        Instruction字段设定我们需要发送的指令,当前我们设定为W25Q64JV_WRITE_ENABLE(0x06);

        Address字段设定我们需要发送的地址(当前指令下不需要发送地址);

        AlternateBytes字段设定交替字节阶段的数据(当前指令下不需要交替字节);

        AddressSize字段设定地址阶段的字节数(当前指令下不需要地址);

        AlternateBytesSize字段设定交替字节阶段的字节数(当前指令下不需要交替字节);

        DummyCycles字段设定空指令阶段的周期数(当前指令下不需要空指令);

        InstructionMode字段设定指令的发送方式,即选用1/2/4线进行指令的发送;根据W25Q64JV芯片手册说明,我们应该选用一线,即QSPI_INSTRUCTION_1_LINE;

        AddressMode字段设定地址的发送方式,即选用1/2/4线进行地址的发送(当前指令下不需要发送地址字节);

        AlternateByteMode字段设定交替字节的发送方式,即选用1/2/4线进行交替字节的发送(当前指令下不需要发送交替字节);

        DataMode字段设定数据的发送方式,即选用1/2/4线进行交替字节的发送(当前指令下不需要发送数据);

        NbData字段设定需要发送的数据字节的数量(当前指令下不需要发送数据);

        DdrMode字段设定使用double date rate,即双数据速率,即一个时钟周期内发送两个bit(当前指令下不需要);

        当我们设定好结构体相关字段后,我们就可以调用HAL_QSPI_Command接口发送请求,由于这条指令只有发送没有接收,所以我们不需要调用HAL_QSPI_Receive获取数据。

        这其实是Quad-SPI间接模式的使用(即通过STM32 Quad-SPI寄存器来控制W25Q64JV)。

        接下来我们再分析一下这条函数调用

        HAL_QSPI_AutoPolling(&hqspi, &cmd, &conf, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)

        首先我们需要看下cmd这个变量,我们设定了Instruction为W25Q64JV_STATUS_REG1(读W25Q64JV状态寄存器1的值);

        我们又定义了一个QSPI_AutoPollingTypeDef类型的变量

        

        字段Match设定匹配值;

        字段Mask设定需要匹配掩码;

        字段Interval设定状态轮询的周期;

        字段StatusBytesSize设定读取的状态字节数;

        字段MatchMode设定匹配的模式(与、或);

        字段AutomaticStop设定匹配成功后是否自动停止;

        由于我们需要检测状态寄存器1的bit1位是否为1(WEL位为1);故我们如下设定:

        

         这其实是Quad-SPI状态轮询机制的使用。

        QSPI_W25Q64JV_WriteEnable这个接口就是W25Q64JV进行擦除、页编程必须要调用的。

        下面我们再看下擦除操作的代码

        

         在擦除接口中,我们首先先发送了写使能指令,然后发送了擦除指令并且设置了擦除首地址,注意该接口入参SectorAddress必须时4096的整数倍,这个是由Flash芯片决定的;擦除指令发送完后我们通过状态轮询模式检查Flash是否真正擦除完毕。

                我们再看一下写数据接口 

        特别要注意的是QSPI_W25Q64JV_Write这个接口实现细节,这个接口会根据当前Flash内部的数据来决定是否需要先进行擦除然后再页编程。

        首先我们通过对入参WriteAddr取整获取该地址所在的区号,取余获取该地址在区内的偏移。

        然后读取该区的所有数据并判断从区内偏移处往后的数据是否全为0xFF;如果是则说明不需要擦除,可以直接编程;否则我们需要擦除整个区,并把当前要写入的数据填充到w25q64jv_buf对应位置后再编程。

        

        至于其他接口的实现细节,大家可以阅读源码分析。

至此,STM32 Quad-SPI的基础知识基本讲解完毕,后续要继续添加中断和DMA的使用。

这篇关于手把手系列--STM32 QSPI操作指南的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/417469

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,