文章目录
一、新建一个工程
二、开启SPI和SFUD组件
详细配置
三、使能宏定义
1.使能QSPI宏
在board.h中
2.使能HAL库函数的QSPI支持
在XXX_hal_config.h中,可能寻找不到,需要自己添加
四、原理图
硬件连接,记住引脚
QSPI_BK1_NCS PG6
QSPI_CLKP F10
QSPI_BK1_IO0 PF8
QSPI_BK1_IO1 PF9
QSPI_BK1_IO2 PF7
QSPI_BK1_IO3 PF6
五、使用CubeMX配置QSPI初始化
1.配置
我使用的是W25Q64 8M字节数据
注意W25Q64系列为8M字节串行Flash芯片,8M = 810241024= 2^23,因此配置Flash Size应该为23-1=22。配置如下:
下面这个Low应该设置为高,我不知道咋设置(尴尬)
如果实在设置不了就等生成代码之后在代码里修改吧。(必须是HIGH)
2.生成代码
在STM32h7xx_hal_msp.c中
/**
* @brief QSPI MSP Initialization
* This function configures the hardware resources used in this example
* @param hqspi: QSPI handle pointer
* @retval None
*/
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hqspi->Instance==QUADSPI)
{
/* USER CODE BEGIN QUADSPI_MspInit 0 */
/* USER CODE END QUADSPI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/**QUADSPI GPIO Configuration
PG6 ------> QUADSPI_BK1_NCS
PF6 ------> QUADSPI_BK1_IO3
PF7 ------> QUADSPI_BK1_IO2
PF8 ------> QUADSPI_BK1_IO0
PF10 ------> QUADSPI_CLK
PF9 ------> QUADSPI_BK1_IO1
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* USER CODE BEGIN QUADSPI_MspInit 1 */
/* USER CODE END QUADSPI_MspInit 1 */
}
}
在main.c 中
/**
* @brief QUADSPI Initialization Function
* @param None
* @retval None
*/
static 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 */
/* QUADSPI parameter configuration*/
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 2;
hqspi.Init.FifoThreshold = 4;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
hqspi.Init.FlashSize = 22;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_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 */
}
3.添加
将上述两个文件添加到board.c文件中
4.编译,下载
发现编译会报错
需要在board.c文件里加上一句
QSPI_HandleTypeDef hqspi; // 结构体
然后编译成功
5.挂载总线成功
执行命令可以看到已经注册了QSPI驱动总线
六、SFUD配置
1.新建两个文件
2.在c文件中编写程序
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-18 冷月枫 the first version
*/
#include "rtdevice.h"
#include "drv_qspi.h"
#include "drv_common.h"
#define QSPI_CS_PIN GET_PIN(G, 6)
// 片选引脚 102
/* 添加设备到QSPI总线 */
int rt_Qspi_opt_w25Q64_init(void)
{
/* 挂载QSPI设备到QSPI总线*/
stm32_qspi_bus_attach_device("qspi1", "qspi10",(rt_uint32_t) QSPI_CS_PIN, 4, RT_NULL, RT_NULL);
#ifdef RT_USING_SFUD
/* 将w25Q64抽象为块设备,以便后续挂载文件系统 */
if(rt_sfud_flash_probe("w25Q64", "qspi10"))
{
rt_kprintf("rt sfud qspiflash probe success\r\n");
return RT_EOK;
}else {
rt_kprintf("rt sfud qspiflash probe fail\r\n");
return -RT_ERROR;
}
#endif
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_Qspi_opt_w25Q64_init);
3.编译,下载,运行
发现设备已经挂载成功
第二个程序是抽象为块设备,为挂载文件系统做准备。