STM32H750片外QSPI启动配置简要

STM32H750片外QSPI启动配置简要


  • 📍参考信息源:《STM32H750片外Flash启动(W25Q64JVSIQ)》
  • 🔖本例程基于Keil MDk开发平台。
  • 🍁配置框架:
    在这里插入图片描述
✨为什么使用要使用QSPI启动方式
不管对于STM32H7系列单片机,还是其他单片机,其自身内部自带的flash容量都是很有限的,容量越大,价格翻倍。QSPI启动方式就是,将主控程序放置到外部SPI flash当中,这样程序空间可以做到很大,仅需要占用一个QSPI硬件接口。同时也方便程序的更新和维护。

🔨QSPI Flash的MDK下载算法制作

  • 🌿以上面的参考源为例。这里以我使用的W25Q64JVSSIQ为例,这是一颗8MB的 SPI flash。
  • 🌿 在FlashDev.c文件中,找到有关宏FLASH_MEM的定义内容,填写对应的参数
#ifdef FLASH_MEM
struct FlashDevice const FlashDevice  =  {FLASH_DRV_VERS,                   /* 驱动版本,勿修改,这个是MDK定的 */"DIY_STM32H7x_QSPI_W25Q64B",    /* 算法名,添加算法到MDK安装目录会显示此名字 */EXTSPI,                           /* 设备类型 */0x90000000,                       /* Flash起始地址 */8 * 1024 * 1024,                  /* Flash大小,8MB */1024,                             /* 编程页大小 */0,                                /* 保留,必须为0 */0xFF,                             /* 擦除后的数值 */1000,                             /* 页编程等待时间 */6000,                             /* 扇区擦除等待时间 */4 * 1024, 0x000000,               /* 扇区大小,扇区地址 */SECTOR_END    
};
#endif 
  • 🌿主控时钟可以和后面的Bootloader程序以及APP程序的时钟初始化一样的。可以直接拷贝过来。
    • 🌿生成的下载算法文件,拷贝到Keil安装目录下的ARM/flash文件夹内,例如:D:\Keil_v5\ARM\Flash

🔧QSPI信息STM32CubeMX软件配置

  • 🔖也就是STM32h7主控搭载的QSPI flash硬件信息填写
  • 🌿QSPI信息配置:后面的的Bootloader程序里面,也保持相同配置。
    在这里插入图片描述
  • 🔖我这里NCS引脚使用的是PB6引脚.其他信号引脚可以根据引脚使用,进行有针对的功能引脚复用。
void MX_QUADSPI_Init(void)
{/* USER CODE BEGIN QUADSPI_Init 0 *//* USER CODE END QUADSPI_Init 0 *//* USER CODE BEGIN QUADSPI_Init 1 *//* USER CODE END QUADSPI_Init 1 */hqspi.Instance = QUADSPI;hqspi.Init.ClockPrescaler = 3;//针对HCLK3分频hqspi.Init.FifoThreshold = 32;hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;hqspi.Init.FlashSize = 24;hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;hqspi.Init.FlashID = QSPI_FLASH_ID_1;hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;if (HAL_QSPI_Init(&hqspi) != HAL_OK){Error_Handler();}/* USER CODE BEGIN QUADSPI_Init 2 *//* USER CODE END QUADSPI_Init 2 */}

📘APP程序程序配置

  • ⚡APP应用程序的IROM1起始地址,一定要和Bootloader程序中的程序跳转地址是一致的才行。
  • 🌿IROM1起始地址配置:(注意这里是0x90000000
    在这里插入图片描述

  • 🔰 Bootloader程序IROM1起始地址保持默认的0x8000000地址位。不要改。
    在这里插入图片描述

  • 🌿APP程序下载和更新,算法文件配置:
    在这里插入图片描述

  • ⚡上面的下载时的RAM大小是1000,需要该大一点,否则下载时会报错。

⛳采坑注意事项

🔰参数差异
  • 🔱由于每个人所使用的主控不同,时钟频率不一样,又或者配置的外置spi flash容量和引脚复用不同,上面的资源参考中,仅仅提供的是一个模板,需要根据个人所使用的硬件差异和参数进行稍微改动。
  • 在个人首次移植时,需要对自己手上的硬件信息有个,基本的了解,主控搭载的外部晶振频率、SPI flash容量、以及flash引脚与主控对应连接的脚位。
  • spi flash容量参数直接根据个人具体型号直接在工程中填写。如果不知道的可以烧录Bootloader程序时启用串口和启用BspQspiBoot_Test()测试函数,并其中插入调试打印信息。
void BspQspiBoot_Test(void)
{bool bTestResult = true;uint8_t ucTestCnt;uint32_t ulTestAddr;uint32_t ulSectorAddr = 0x2000;ulFlashID = BspQspiBoot_ReadID();//  if(ulFlashID != 0x00EF4018) //16MB:15679512if (ulFlashID != 0x00EF4017) // 8MB:15679511{bTestResult = false;}elseHAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin | LED3_Pin, GPIO_PIN_RESET);while (bTestResult == false){HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin);HAL_Delay(800);//		printf("FlashID:%d \r\n",ulFlashID);//查看容量,十进制的}BspQspiBoot_EraseSector(ulSectorAddr);for (ucTestCnt = 0; ucTestCnt < 16; ucTestCnt++){ulTestAddr = ulSectorAddr + (ucTestCnt * QSPI_FLASH_PAGE_SIZE);{uint16_t i;for (i = 0; i < sizeof(ucaTestBuff); i++){ucaTestBuff[i] = i;}}BspQspiBoot_WritePage(ucaTestBuff, ulTestAddr, sizeof(ucaTestBuff));memset(ucaTestBuff, 0, sizeof(ucaTestBuff));BspQspiBoot_ReadBuff(ucaTestBuff, ulTestAddr, sizeof(ucaTestBuff));{uint16_t i;for (i = 0; i < sizeof(ucaTestBuff); i++){if (ucaTestBuff[i] != i){bTestResult = false;break;}}}}while (bTestResult == false);while (1){}
}
  • 🌿外部时钟时钟初始化函数可以通过STM32CubeMX配置设定好参数自动生成工程,然后拷贝对应的时钟初始化函数到工程中进行替换。来匹配个人使用的主控芯片。

  • 🌿QSP NCS引脚复用调整:

#define QSPI_CS_PIN GPIO_PIN_6 // 注意修改 GPIO_PIN_10
#define QSPI_CS_GPIO_PORT GPIOB
#define QSPI_CS_GPIO_AF GPIO_AF10_QUADSPI // 注意修改 GPIO_AF9_QUADSPI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/525432.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java】快速排序

文章目录 一、什么是快速排序二、基准元素的选择1、选择第一个元素2、随机选择 三、元素的交换1、双边循环法2、单边循环法 一、什么是快速排序 快速排序是由冒泡排序演变而来&#xff0c;比冒泡排序更快的排序算法。之所以快&#xff0c;是因为快速排序用了分治法。 相同的是…

探索手指套的多功能用途

什么是手指套&#xff1f; 手指套&#xff0c;戴在手指上的用品。作为一种小巧实用的用品&#xff0c;在我们的生活中扮演着多种角色。无论是在工业生产中的保护&#xff0c;医疗操作中的防护&#xff0c;还是日常生活中的装饰&#xff0c;甚至是性生活中的辅助&#xff0c;手…

数据结构从入门到精通——队列

队列 前言一、队列1.1队列的概念及结构1.2队列的实现1.3队列的实现1.4扩展 二、队列面试题三、队列的具体实现代码Queue.hQueue.ctest.c队列的初始化队列的销毁入队列出队列返回队头元素返回队尾元素检测队列是否为空检测元素个数 前言 队列是一种特殊的线性数据结构&#xff…

Rust教程:How to Rust-从开始之前到Hello World

本文为第0篇 专栏简介 本专栏是优质Rust技术专栏&#xff0c;推荐精通一门技术栈的蟹友&#xff0c;不建议基础的同学&#xff08;无基础学Rust也是牛人[手动捂脸]&#xff09; 感谢Rust圣经开源社区的同学&#xff0c;为后来者提供了非常优秀的Rust学习资源 本文使用&…

银河麒麟V10 安装部署大数据管理软件 DataSophon

一、概览 1、愿景 致力于快速实现部署、管理、监控以及自动化运维大数据云原生平台&#xff0c;帮助您快速构建起稳定、高效、可弹性伸缩的大数据云原生平台。 2、DataSophon是什么 《三体》&#xff0c;这部获世界科幻文学最高奖项雨果奖的作品以惊艳的"硬科幻"…

ARM/Linux嵌入式面经(二):芯片原厂

uart如何进行通信&#xff0c;模块发给uart数据信息后经历了什么 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发传输器&#xff09;是一种用于串行通信的协议&#xff0c;它使用一对传输线&#xff08;TX和RX&#xff09;进行双向通信…

结构体内存对齐详解

目录 结构体对齐&#xff1a; 为什么要进行内存对齐&#xff1f; 关于结构体的详解文章&#xff1a;C语言结构体详解_结构体变量和结构体类型举例-CSDN博客 结构体对齐&#xff1a; 存储的时候和当前存储的成员类型字节大小和默认对齐数比较&#xff0c;取小值 存在该对齐数的…

大语言模型的“大”体现在哪里

大语言模型中的"大"通常体现在以下几个方面&#xff0c;参数数量&#xff0c;训练数据和计算资源&#xff1a; 参数数量&#xff1a; 大语言模型的一个显著特征是其庞大的参数数量。参数的数量决定了模型的复杂度和表示能力。更多的参数通常意味着模型可以捕捉更复…

【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点

文章目录 题目思路解答 题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 3&…

linux系统---selinux

目录 前言 一、SELinux 的作用及权限管理机制 1.SELinux 的作用 1.1DAC 1.2MAC 1.3DAC 和 MAC 的对比 2.SELinux 基本概念 2.1主体&#xff08;Subject&#xff09; 2.2对象&#xff08;Object&#xff09; 2.3政策和规则&#xff08;Policy & Rule&#xff09; …

手写简易操作系统(三)--加载Loader

前情提要 上一节我们讲了如何启动计算机&#xff0c;这一节我们讲如何加载内核&#xff0c;内核是存在于硬盘上的一段程序&#xff0c;要加载这段程序&#xff0c;那么必然需要从硬盘上读取数据&#xff0c;这里我们就需要使用 ATA PIO 模式 根据ATA规范&#xff0c;所有符合A…

算法---双指针练习-4(盛水最多的容器)

题目 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;盛水最多的容器 2. 讲解算法原理 算法的主要思路是使用双指针的方法&#xff0c;通过不断调整指针的位置来计算面积&#xff0c;并更新最大面积。具体步骤如下&#xff1a; 初始化左指针x为数组…