@STM32 QSPI双闪存操作

使用CubeMX或者CubeIDE生成框架

使用野火的开发板,MCU型号为stm32h750/743,他们家核心板上使用了QSPI挂了2片FLASH,型号为W25Q256,但是提供的例程里只有单个FLASH的QSPI操作例程。根据了解,他们本来计划在核心板上只保留1片FLASH的,只是我买的比较早了 。

在开发板上的原理图接线如上,其中PB2为时钟,PG6为片选,两片FLASH共用。

QSPI双FLASH模式的配置注意把片选设置为1个片选选中2片FLASH就可以了,其他引脚设置按照原理图中进行设置即可。在CubeIDE中,点击保存后会自动弹框,询问是否生成代码,非常的方便。

双闪存需要注意的地方

开发板厂家提供了该flash的底层驱动,bsp_qspi_flash.c bsp_qspi_flash.h,在驱动里提供了擦除、写入、读取等函数接口,在擦除和写入的函数中都调用了一个轮询等待的子函数。因为FLASH进行擦除和写入都需要耗费一定时间,在这段时间内无法进行其他操作,比如读取,因此在FLASH内部有许多状态寄存器。轮询等待的实现就是去查询相应的寄存器,只有当表示空闲的那一位数据为1时,表示可以进行读取操作,为0则表示繁忙。

/*** @brief  擦除QSPI存储器的指定块* @param  BlockAddress: 需要擦除的块地址* @retval QSPI存储器状态*/
uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
{QSPI_CommandTypeDef s_command;/* 初始化擦除命令 */s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;s_command.Instruction       = SECTOR_ERASE_CMD;s_command.AddressMode       = QSPI_ADDRESS_1_LINE;s_command.AddressSize       = QSPI_ADDRESS_32_BITS;s_command.Address           = BlockAddress;s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;s_command.DataMode          = QSPI_DATA_NONE;s_command.DummyCycles       = 0;s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;/* 启用写操作 */if (QSPI_WriteEnable() != QSPI_OK){return QSPI_ERROR;}/* 发送命令 */if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK){return QSPI_ERROR;}/* 配置自动轮询模式等待擦除结束 */if (QSPI_AutoPollingMemReady(W25Q256JV_SECTOR_ERASE_MAX_TIME) != QSPI_OK){return QSPI_ERROR;}return QSPI_OK;
}

厂家提供的驱动只有单个FLASH状态寄存器读取的设置,因此需要修改该函数。

首先看一下原来的自动轮询模式等待函数QSPI_AutoPollingMemReady

/*** @brief  读取存储器的SR并等待EOP* @param  hqspi: QSPI句柄* @param  Timeout 超时* @retval 无*/
static uint8_t QSPI_AutoPollingMemReady(uint32_t Timeout)
{QSPI_CommandTypeDef     s_command;QSPI_AutoPollingTypeDef s_config;/* 配置自动轮询模式等待存储器准备就绪 */s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;s_command.Instruction       = READ_STATUS_REG1_CMD;s_command.AddressMode       = QSPI_ADDRESS_NONE;s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;s_command.DataMode          = QSPI_DATA_1_LINE;s_command.DummyCycles       = 0;s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;s_config.Match           = 0x00;s_config.Mask            = W25Q256JV_FSR_BUSY;s_config.MatchMode       = QSPI_MATCH_MODE_AND;s_config.StatusBytesSize = 1;s_config.Interval        = 0x10;s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;if (HAL_QSPI_AutoPolling(&hqspi, &s_command, &s_config, Timeout) != HAL_OK){return QSPI_ERROR;}return QSPI_OK;
}

该函数是向FLASH发送READ_STATUS_REG1_CMD(05H)命令读取FLASH内部的寄存器,我们只关注这个状态寄存器的第0 位“BUSY”,当这个位为“1”时,表明FLASH 芯片处于忙碌状态,它可能正在对内部的存储矩阵进行“擦除”或“数据写入”的操作。调用HAL_QSPI_AutoPolling 库函数,设定命令参数及自动轮询参数,最后设定超时返回,如果在超时等待时间内确定FLASH 就绪则返回存储器就绪状态,否则返回存储器错误。其实主要就是检查它的W25Q256FV_FSR_BUSY (01H)(即BUSY 位),通过QUADSPI_PSMAR
与**QUADSPI_QUADSPI _PSMKR **作‘与’运算或者是作‘或’运算。如果满足条件才退出本函数,以便继续后面与FLASH 芯片的数据通讯。
单个FLASH需要判断一个字节,而双闪存操作的情况下,有可能一片FLASH已经处于空闲状态,而另一片还在繁忙,若此时进行其他操作则会导致结果异常(亲测只判断一片空闲就写入数据,导致只有一片FLASH中有数据)。由于双闪存模式下HAL库读取为:第一个字节为FLASH1的数据,第二个字节为FLASH2的数据,第三个字节为FLASH1的数据,这样奇偶交替,因此轮询等待读取状态寄存器的函数
修改为:

static uint8_t QSPI_AutoPollingMemReady(uint32_t Timeout)
{QSPI_CommandTypeDef     s_command;QSPI_AutoPollingTypeDef s_config;/* 配置自动轮询模式等待存储器准备就绪 */s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;s_command.Instruction       = READ_STATUS_REG1_CMD;s_command.AddressMode       = QSPI_ADDRESS_NONE;s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;s_command.DataMode          = QSPI_DATA_1_LINE;s_command.DummyCycles       = 0;s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;s_config.Match           = 0x00;s_config.Mask            = W25Q256JV_FSR_BUSY + (W25Q256JV_FSR_BUSY <<8);/*双闪存判断两个字节*/s_config.MatchMode       = QSPI_MATCH_MODE_AND;s_config.StatusBytesSize = 2;/*双闪存判断两个字节*/s_config.Interval        = 0x10;s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;if (HAL_QSPI_AutoPolling(&hqspi, &s_command, &s_config, Timeout) != HAL_OK){return QSPI_ERROR;}return QSPI_OK;
}

这样就可以判断出两片FLASH都处于就绪状态了

STM32 QSPI双闪存操作相关推荐

  1. STM32之 W25Q128闪存(SPI协议)驱动代码(程序稳定,清晰明了)

    第一部分:W25Q128代码头文件 (W25Q128.h) #ifndef W25Q128_H #define W25Q128_H #include "stm32f10x.h" # ...

  2. stm32闪存的理解

    STM32f1xxx的闪存模块由:主存储器.信息块和闪存存储器接口寄存器等3部分组成. 各个部分的大小因不同型号有一定的差异,数据手册中可以看到 小容量产品主存储块1-32KB,每页1KB.系统存储器 ...

  3. nRF52832闪存FDS使用(SDK17.1.0)

    陈拓 2022/10/29-2022/11/22 1. 简介 对于Nordic芯片内部FLASH存储管理有两种方式,FS (Flash Storage)和FDS (Flash Data Storage ...

  4. 洋桃开发板笔记(六 ) STM32自带的Flash闪存使用,主要配合其他外设

    Flash闪存与其他外设的使用 杜洋工作室 www.DoYoung.net 洋桃电子 www.DoYoung.net/YT 在此声明一下所有代码均为 杜洋工作室 的不允许复制,转发等,本人只是在此程序 ...

  5. (39)STM32——FLASH闪存

    目录 学习目标 成果展示 介绍 组成 主存储器 系统存储器 OTP 区域 选项字节 读取 编程 寄存器 步骤 擦除 扇区擦除 批量擦除 寄存器 代码 总结 学习目标 本节我们要来介绍一下关于FLASH ...

  6. STM32存储器组织-STM32存储器映像-嵌入式SRAM-STM32位段-嵌入式闪存-STM32启动配置

    STM使用说明第二篇 [1]STM32存储器组织 [2]STM32存储器映像 [3]嵌入式SRAM [4]STM32位段 [5]嵌入式闪存 [6]STM32启动配置 [1]STM32存储器组织 程序存 ...

  7. 使用大于 16MB 的闪存时, Zynq 和 QSPI 的复位要求

    原文地址:http://blog.csdn.net/pengwangguo/article/details/54963702 哪个 Zynq-7000 平台会受影响? 在以下任何配置中使用大于 16M ...

  8. 使用大于 16MB 的闪存时 Zynq 和 QSPI 的复位要求

    哪个 Zynq-7000 平台会受影响? 在以下任何配置中使用大于 16MB QSPI 闪存进行启动的任何 Zynq-7000 平台:单路.双堆叠.双路并行. 注意:具有两个 16MB QSPI 闪存 ...

  9. 【STM32】详解嵌入式中FLASH闪存的特性和代码示例

    一.存储器 我们正常编译生成的二进制文件,需要下载烧录到单片机里面去,这个文件保存在单片机的ROM(read only memory)中,所有可以完成这种特性的存储介质都可以称为ROM. 分类 ROM ...

最新文章

  1. 重构机房收费系统你要用的——异常处理和抛出异常(try catch finally)——(vb.net)...
  2. Android Canvas 绘图
  3. python 常量_大疆机甲大师Python开发: 两只老虎
  4. Windows和Linux环境下搭建SVN服务器
  5. PageRanke算法
  6. Angular Observable数据类型的单元测试数据准备
  7. WeakReference与SoftReference
  8. java mediator_java—mediator中介模式
  9. k-means及变种
  10. jni java与c++交互返回三维数组jobjectArray
  11. cisco路由器配置DHCP实例
  12. LoadRunner教程(28)-LoadRunner连接mysql
  13. Win10 1607 频繁断网,迅雷断网以及迅雷下载崩溃解决方案
  14. 013.自驾游加油方案
  15. educoder:第3关:嵌套循环 - 跃迁能量表
  16. MATLAB长除法求z变换逆变换
  17. 发卡网源码(企业和个人发卡网源码二合一)及代理系统附搭建教程
  18. vue过滤器如何使用
  19. 吴恩达新动向揭晓:加入精神健康领域的人工智能Woebot
  20. 菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

热门文章

  1. 一篇介绍LSTM的博客,写的很好
  2. 真是嘴上硬的人大多心里软,又把事做了还讨不了好
  3. tomcat无法启动 Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardConte
  4. python线上培训班5月是淡季
  5. 双向链表的定义及基本操作
  6. Springboot毕设项目班费管理系统16me6(java+VUE+Mybatis+Maven+Mysql)
  7. 给母猪接生,这事我干过!
  8. Uncaught SyntaxError: Unexpected identifier 和 Uncaught SyntaxError: Invalid or unexpected token
  9. 通过ping++平台完成移动端H5支付
  10. Tomcat 如何实现一键式启停?