Part1开发平台

野火STM32H750Pro开发板,QSPI双片W25Q256,原理图如下

参考资料:百度搜索datasheet5,进入该网站搜芯片型号W25Q256即可获取PDF。简要说明一下就是单个W25Q256使用按页(256字节一页)编程写入,按扇区(4KB)、块(64KB或32KB)、或整片来进行擦除。

Part2 搭建工程

首先按照这篇博客中的方法搭建工程:

(66条消息) stm32cubemx无法生成工程_工程师笔记 | 通过 STM32CubeMX制作外部Flash的烧写驱动 (.stdlr)…_瓷tun的博客-CSDN博客

这里我的工程结构与该文章保持一致,但是由于用的开发板和博主的不一样,FLASH芯片、模式也不一样,因此驱动那一块我还是按照开发板的例程来移植,不过main函数的执行流程还是可以借鉴的。

QSPI驱动可自行移步野火官方资料下载中心获取

Part3 调试过程中出现的问题——FLASH读写失败

第一次测试,main函数代码执行步骤为:

1.数组编号 0~FF的循环

2.擦除块,并写入

3.配置为直接映射

4.打开Memory监测

监测结果如下,0x90000000~0x900001FF 数据写入失败仍然为FF

之后的数据只有一片FLASH操作成功。

第二次测试,修改代码为:

1.擦除6块

2.配置为直接映射,打开Memory监测

其中块大小为0x10000,理论上0x90060000之后应该为非擦除状态

但是反而0x90060000之前的未擦掉,之后的擦掉了,也就是说FLASH的写入和擦除都未能成功

异常数据似乎没有规律

第三次测试:使用整片擦除代替上面的6块擦除,发现根本没有擦掉。而且整片擦除函数执行很快,明显不符合实际。

检查了一下cubeMX配置的工程,发现引脚有的是高速,有的是低速,修改好之后发现还是不行。

第四次测试:直接将工程修改为单个FLASH的模式,发现整片擦除不成功,只能块擦除,查看FLASH的3个寄存器,发现在reg1中BP3 BP2 BP1 BP0为0001,也就是说使能了某种保护机制,FLASH中有一小段无法被改动。抱着试一试的想法,向寄存器reg1写入全0之后,整片擦除函数得以运行。因此怀疑前三次FLASH的操作失败是由于两片FLASH均受到了保护机制影响。

第五次测试:将工程改回双FLASH模式,读取寄存器,发现两片FLASH reg1 为0x06fe 。也就是FLASH1 的 BP3 BP2 BP1 BP0为0001(不知道为啥,第四次明明改成全0了,现在又恢复了); FLASH2的 SRP TB BP 3 BP 2 BP 1 BP 0 WEL BUSY分别为11111110,也就是说除了BUSY为0其他全是1。根据W25Q256芯片手册,FLASH2处于硬件WP引脚有效的状态,即当WP引脚为高电平时,才能对寄存器进行改写,以及设置写使能,并且保护范围是整片。尝试了一下写全0,发现只有FLASH1可以改写寄存器,果然FLASH2还是受到WP引脚影响啊。

尝试了在初始化的时候将WP引脚设置成上拉,发现没有用。直接取消GPIO初始化复用QSPI引脚,初始化为普通输出IO,然后在写寄存器为全0之前,使用 HAL_GPIO_WritePin 将该引脚拉高,结果OK,寄存器被成功改写。成功解决。

再次测试写64MB数据,结果又失败了…重新Debug发现FLASH1的局部保护又被打开了。总结前面几次得到一个结论:如果操作不当,或者代码调试还有问题,那么有可能会触发芯片的保护机制,调试过程中难免的

调整宏定义大小:

#define W25Q256JV_FLASH_SIZE                  0x4000000 /* 双片 64MB  */
#define W25Q256JV_BLOCK_SIZE                  0x20000   /*单片64KBytes  256页为1个block,两片则为128KB*/
#define W25Q256JV_BLOCK_COUNT                 512       /* 512 个block */
#define W25Q256JV_SECTOR_SIZE                 0x2000   /* 4KBytes  *2*/
#define W25Q256JV_PAGE_SIZE                   0x200     /* 1页256*2字节 */

最终在单步调试的情况下得以解决
但是全速运行会出现有些Block只有一片FLASH成功,猜测应该是等待FLASH操作完成的判断写得不对,修改等待代码

void QSPI_FLASH_Wait_Busy(void)
{uint32_t _reg;while(1){_reg = QSPI_FLASH_ReadStatusReg(1);if((_reg & 0x0101)==0) break;}
}

将等待插入到FLASH操作之前,最终解决。

最后检查一下边界,即最多可以读写多少字节。

发现0x90000000~0x93FFFFFF 共64MB空间读写没问题。

Part4 main代码

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_QUADSPI_Init();/* USER CODE BEGIN 2 */uint8_t buffer_test[0x10000] = {0};/*按半个block来定义数组大小,否则占用内存太大,引起无法调试*/uint8_t readbuf[128] = {0};uint32_t var = 0;BSP_QSPI_Init();uint32_t reg[3] = {0};
//  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, 1);QSPI_FLASH_WriteStatusReg(1,0);reg[0] =  QSPI_FLASH_ReadStatusReg(1);reg[1] = QSPI_FLASH_ReadStatusReg(2);reg[2] = QSPI_FLASH_ReadStatusReg(3);var = QSPI_FLASH_ReadDeviceID();//读ID试试var = QSPI_FLASH_ReadID();BSP_QSPI_Read(readbuf,0,128);//初始化数组为for (var = 0; var < 0x10000; var++) {buffer_test[var] = (var & 0xff);}for (var = 0; var < W25Q256JV_BLOCK_COUNT; var++) {//扇区擦除BSP_QSPI_Erase_Block64(var * W25Q256JV_BLOCK_SIZE);QSPI_FLASH_Wait_Busy();//扇区写入BSP_QSPI_Write(buffer_test,var * W25Q256JV_BLOCK_SIZE,0x10000);//先写半个blockQSPI_FLASH_Wait_Busy();BSP_QSPI_Write(buffer_test,var * W25Q256JV_BLOCK_SIZE + 0x10000,0x10000);//再写半个blockQSPI_FLASH_Wait_Busy();}if (QSPI_EnableMemoryMappedMode() != QSPI_OK) {while (1){}}//比较内容for (var = 0; var < W25Q256JV_BLOCK_COUNT; var++) {if (memcmp(buffer_test,(uint8_t*) (0x90000000 + var * W25Q256JV_SECTOR_SIZE),W25Q256JV_SECTOR_SIZE) != HAL_OK) {while (1);}}/* USER CODE END 2 */while (1){}
}

彻底拿下QSPI双闪存W25Q256| STM32H750| QSPI 双FLASH |cubeIDE |下载算法(一)相关推荐

  1. STM32 QSPI双闪存操作

    @STM32 QSPI双闪存操作 使用CubeMX或者CubeIDE生成框架 使用野火的开发板,MCU型号为stm32h750/743,他们家核心板上使用了QSPI挂了2片FLASH,型号为W25Q2 ...

  2. 内存颗粒和闪存颗粒的区别_NAND Flash闪存颗粒与SSD知识深度解析

    谈闪存,须从Wafer开始.Wafer即晶圆,是半导体组件"晶片"或"芯片"的基材,从沙子里面高温拉伸生长出来的高纯度硅晶体柱(Crystal Ingot)上切 ...

  3. 闪存,ROM,Nor Flash,NAND Flash

    物理结构分类 ROM 固定ROM 可编程ROM 可擦除可编程ROM EPROM EEPROM Flash Memory NOR Flash NAND Flash 3D NAND Flash 固定ROM ...

  4. [闪存 第2回] NAND Flash 原理与挑战

    Flash 简介 Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory ...

  5. [闪存2.1.6] NAND FLASH基本编程(写)操作及原理_NAND FLASH Program Operation 源码实现

    声明 主页: 元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言. 个人辛苦整理,付费内容,禁止转载. 内容摘要

  6. [闪存2.1.3] 固态硬盘闪存的物理学原理_NAND Flash 的读、写、擦工作原理

    ​ 声明 ​​ 主页: 元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言. 个人辛苦整理,付费内容,禁止转载.​ 内容摘要 2.1.3.1 Flash 的物理学原理与发明历程 经典物理学 ...

  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. 内存、外存、硬盘、磁盘、闪存,傻傻分不清?

    引言   平时我们买手机,关注最多的配置就是内存了,比如6G+64G.8G+128G等等.但是很多人容易弄混这两个概念.之前我遇到有人问我,说买平板是64G内存,还是128G内存好,128G有点贵,6 ...

  10. 《信息存储与管理(第二版):数字信息的存储、管理和保护》—— 2.12 闪存盘简介...

    本节书摘来异步社区<信息存储与管理(第二版):数字信息的存储.管理和保护>一书中的第2章,第2.12节,作者:[新加坡]G.Somasundaram ,[美]Alok Shrivastav ...

最新文章

  1. HDU 1273 漫步森林
  2. 数据库开发个人总结(ADO.NET小结)
  3. 为什么Python没有main函数?
  4. MapReduce编程实战之“高级特性”
  5. html设置excel打开新窗口,怎么在excel的大页面上设置第几页第几页的
  6. 【渝粤教育】国家开放大学2018年春季 0025-21T数据结构 参考试题
  7. 关于sprintf和snprintf的比较
  8. mysql利用tgz恢复_Mysql备份与恢复方法_MySQL
  9. Linux基本命令(二)
  10. 涨疯了!国产鞋被爆炒,原价1499元卖48889元,有人几天赚一辆车
  11. anki 新的卡片类型_Anki 常用操作方法合集(一)常用操作1
  12. python自动发公众号_itchatmp | 基于python微信公众号接口
  13. [2020.12.6 解决docker容器乱码问题] 一劳永逸export env LANG=C.UTF-8永久支持中文,无需Dockerfile重建镜像
  14. 电影院传出的哭声《比悲伤更悲伤的故事》程序员们怎么看?
  15. Android四大组件之Activity(intent、ActivityThread)
  16. FL Studio教程之Fruity Wrapper插件讲解
  17. 如何是音乐再ios展台
  18. 51-单片机及开发板介绍
  19. 第2课:郭盛华课程_VB编程之常用重要函数
  20. MCNP6软件的安装步骤

热门文章

  1. kettle教程-Windows下安装及简单使用
  2. AltiumDesigner(三):PCB导出Gerber文件及各个Gerber文件说明
  3. 数据结构(直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序、快速排序)
  4. 前端-图片压缩,基于vue/webpack的tinypng插件
  5. 电影院购票系统ssm (含论文)
  6. stdio.h 之 printf
  7. CoppeliaSim(Vrep)动力学仿真入门设置
  8. xshell官方个人免费版申请下载使用
  9. 大一计算机实验报告excle,excel实验报告总结
  10. css给文字设置动态效果,利用纯CSS实现动态的文字效果实例