@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. 关闭VMware 不用的服务
  2. spring 全局变量_精华:关于Spring的15点总结
  3. 在python中查看关键字需要在python解释器中执行_现有代码 d={},在Python3解释器中执行 d[([1,2])] = 'b'得到的结果为( )。...
  4. python: line=f.readlines() 后如何消除line中的’\n’
  5. linux结束进程_生人勿近之Linux里养僵尸
  6. pipeline 发布war包
  7. 苹果又想出涨价新招,iPhone 12将标配AirPods耳机?
  8. java跨系统和跨域_java web服务解决跨域问题
  9. linux下打印用户态段错误信息的一种方法
  10. 从零基础入门Tensorflow2.0 ----五、25TF1.0自定义estimator
  11. java中包定义_java中包的定义与使用
  12. 信号与系统的基本概念与通信系统模型
  13. C# 回调函数的实现和应用场景
  14. Java 遍历JsonNode
  15. 如何在vue3.0项目中集成Element-plus
  16. Birt时间参数添加My97日历控件
  17. 信息系统项目管理师-3项目立项管理
  18. android如何使用so库,Android 使用SO库
  19. C语言程序设计作业04
  20. 算法图解 第7章 狄克斯特拉算法

热门文章

  1. Handlebars 安装
  2. 停车还能360全方位影像_德国首创“新型汽车”不仅能无人驾驶,还能360度无死角停车...
  3. android开源项目!来一份全面的面试宝典练练手,通用流行框架大全
  4. OpenTSDB的故障排除
  5. c#动画(两点动画,旋转动画,变色动画)及案例
  6. python计算excel crc_CRC计算器的Python实现
  7. 用 Java 实现天天酷跑(附源码),这个真的有点强了!
  8. Github上的开源项目4
  9. 用于降低EMI的时钟展频技术
  10. 【蠢哭自己系列】Linux转到桌面目录下