STM32H750片外QSPI启动配置简要

STM32H750片外QSPI启动配置简要


✨为什么使用要使用QSPI启动方式
不管对于STM32H7系列单片机,还是其他单片机,其自身内部自带的flash容量都是很有限的,容量越大,价格翻倍。QSPI启动方式就是,将主控程序放置到外部SPI flash当中,这样程序空间可以做到很大,仅需要占用一个QSPI硬件接口。同时也方便程序的更新和维护。

🔨QSPI Flash的MDK下载算法制作

  • 🌿以上面的参考源为例。这里以我使用的W25Q64JVSSIQ为例,这是一颗8MB的 SPI flash。
  • 🌿 在FlashDev.c文件中,找到有关宏FLASH_MEM的定义内容,填写对应的参数
c 复制代码
#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引脚,
c 复制代码
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()测试函数,并其中插入调试打印信息。
c 复制代码
void BspQspiBoot_Test(void)
{
  bool bTestResult = true;
  uint8_t ucTestCnt;
  uint32_t ulTestAddr;
  uint32_t ulSectorAddr = 0x2000;

  ulFlashID = BspQspiBoot_ReadID();

  //  if(ulFlashID != 0x00EF4018) //16MB:15679512
  if (ulFlashID != 0x00EF4017) // 8MB:15679511
  {
    bTestResult = false;
  }
  else
    HAL_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引脚复用调整:

c 复制代码
#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