SMT32F767通过STM32CUBE HAL库配置QSPI和W25Q256驱动

一、芯片管脚和MCU管脚、时钟

在这里插入图片描述
在这里插入图片描述
时钟配置:
在这里插入图片描述
在这里插入图片描述

二、生成QSPI的代码

代码里面挺多备注了,不懂得再去刷一刷正点原子的视频吧,结合手册来看,来源都是正点原子的代码。
头文件qspi.h

#ifndef __QSPI_H
#define __QSPI_H
#include "stm32f7xx_hal.h"
//QSPI功能配置
u8 QSPI_Init(void);
//QSPI 底层驱动 引脚配置 时钟使能
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi);
//QSPI发送命令
void QSPI_Send_CMD(u32 Instruction,u32 Address,u32 DummyCycles,u32 InstructionMode ,
u32 AddressMode , u32 AddressSize ,u32 DataMode);
//发送数据给W25Q256
u8 QSPI_Transmit(u8*buf,u32 datalen);
//接受W25Q256数据到数组中
u8 QSPI_Receive(u8*buf,u32 datalen);
//关闭QSPI通讯
void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi);
#endif
#include "qspi.h"
QSPI_HandleTypeDef hqspi;//QSPI句柄

/**
  * @brief QSPI功能配置
QSPI_BK2_NCS	PC11
QSPI_BK2_IO0	PE7
QSPI_BK2_IO1	PE8
QSPI_BK2_IO2	PE9
QSPI_BK2_IO3	PE10
QSPI_BK2_CLK	PB2
  * @param None
  * @retval None
  */
u8 QSPI_Init(void)
{
   

  hqspi.Instance = QUADSPI;//QSPI
  //时钟预分频系数,在QUADSPI_CR控制寄存器的PRESCALER位[31:24]
  //FCLK=FAHB/(ClockPrescaler+1) QSPI挂载在AHB总线上
  //范围0~255 QSPI分频比,W25Q256的最大频率为104M,这里的AHB频率为216M
  hqspi.Init.ClockPrescaler = 2;//QSPI频率=216/(2+1)=72M
  hqspi.Init.FifoThreshold = 4;//FIFO阈值 CR中FTHRES[4:0] FIFO中写入4+1个字节后,FTF标志置1
  hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;   //采样移位CR4 1=半个周期之后再采样  (DDR模式下,必须设置为0)
  //POSITION_VAL (0X2000000)获取VAL值的最高位位数
  //Flash字节数=2^(FlashSize+1)
  //POSITION_VAL(0X2000000)=26  2^26=67108864 字节=64MB   计算结果错误,难道是POSITION_VAL(0X2000000)=25???
  hqspi.Init.FlashSize = POSITION_VAL(0X2000000)-1; //DCR[20:16] Flash大小32MB=256Mb  
  //片选高电平时间为四个时钟(13.8*4=55.2ns) 手册里面的tSHSL参数
  //发送Flash命令之间必须保持高电平的最少CLK周期数
  hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE;//片选高电平时间 DCR 10:8
//模式设置 DCR0	
	//nCS为高电平(片选释放)时,CLK必须保持低电平,这称为模式0 QSPI_CLOCK_MODE_3
	//nCS为高电平(片选释放)时,CLK必须保持高电平,这称为模式3 QSPI_CLOCK_MODE_0
  hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;//模式0 
  //选择FLASH CR7	FSEL
  //0选择FLASH1 1选择FLASH2  DFM=1时忽略该位,因为DFM时双闪存模式
  hqspi.Init.FlashID = QSPI_FLASH_ID_2;//第一片Flash
  //双闪存模式 CR6 DFM   0禁止 1使能
	hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;//禁止双闪存模式
  if (HAL_QSPI_Init(&hqspi) != HAL_OK)//QSI初始化失败
  {
   
    return 1;//初始化失败
  }else 
  {
   
	  HAL_QSPI_MspInit(&hqspi);
	  return 0;//初始化成功
  }
}


/**
* @brief QSPI 底层驱动 引脚配置 时钟使能
*此函数会被QSPI_Init(void)函数调用
* @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_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**QUADSPI GPIO Configuration
    PB2     ------> QUADSPI_CLK
    PE7     ------> QUADSPI_BK2_IO0
    PE8     ------> QUADSPI_BK2_IO1
    PE9     ------> QUADSPI_BK2_IO2
    PE10     ------> QUADSPI_BK2_IO3
    PC11     ------> QUADSPI_BK2_NCS
    */
	 //PB2 时钟管脚
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	//PE7、8、9、10  IO0、1、2、3
	//数据管脚
    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

	//片选管脚
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* USER CODE BEGIN QUADSPI_MspInit 1 */

  /* USER CODE END QUADSPI_MspInit 1 */
  }

}


//QSPI发送命令
void QSPI_Send_CMD(u32 Instruction,u32 Address,u32 DummyCycles,u32 InstructionMode ,
	u32 AddressMode , u32 AddressSize ,u32 DataMode)
{
   
	QSPI_CommandTypeDef CmdHandler;
	
	CmdHandler.Instruction=Instruction;//指令
	CmdHandler.Address=Address;//地址
	CmdHandler.DummyCycles=DummyCycles;//设置空指令周期数
	CmdHandler.InstructionMode=InstructionMode;//指令模式
	CmdHandler.AddressMode=AddressMode;//地址模式
	CmdHandler.AddressSize=AddressSize;//地址长度
	CmdHandler.DataMode=DataMode;//数据模式
	CmdHandler
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值