基于STM32H743 QSPI串行读写外部FLASH

软件开发大郭
0 评论
/
46 阅读
/
17965 字
28 2022-04
分类:

bsp.h

/*
 * bsp.h
 *
 *  Created on: Apr 22, 2021
 *      Author: Administrator
 */

#ifndef BSP_H_
#define BSP_H_

#include "main.h"
#include "stdio.h"
#include "string.h"

void user_Assert(char *file,uint32_t line);


#endif /* BSP_H_ */

bsp.c

/*
 * bsp.c
 *
 *  Created on: Apr 22, 2021
 *      Author: Administrator
 */
#include "bsp.h"


/**
  * 函数功能: 检查代码异常,打印出异常的位置(文件名与行号)
  * 输入参数: file: 源代码文件名称。关键字__FILE__表示源代码文件名。
  *        line: 代码行号,关键字__LINE__表示源代码行号
   * 返回值:  void

  * 说明:
  *    1、在需要断言的地方直接调用user_Assert(__FILE__,__LINE__);
  */
void user_Assert(char *file,uint32_t line)
{
	printf("Wrong parameters value: file %s on line %d\r\n",file, (unsigned int)line);

    /* 这是一个死循环,断言失败时程序会卡此处死机,以便于用户差错 */
	if(line == 0)
	{
		return;
	}
	while(1)
	{

	}
}

bsp_qspi_w25q128.h

/*
 * bsp_quadspi_W25Q128.h
 *
 *  Created on: Apr 21, 2021
 *      Author: Administrator
 *
  *  该bsp用于华邦的w25q128JV,跟华邦的w25q128JV不一样
  *  坑爹的
 */

#ifndef BSP_QSPI_W25Q128_H_
#define BSP_QSPI_W25Q128_H_

#include "bsp.h"
#include "quadspi.h"
#include "stdio.h"

/* 宏定义 --------------------------------------------------------------------*/
#define FLASH_BEGIN_ADDRESS 0x00000

#define W25Q128FV_FLASH_SIZE                  0x1000000 /* 128 MBits => 16MBytes */
#define W25Q128FV_BLOCK_SIZE                  0x10000   /* 256 Blocks of 64KBytes */
#define W25Q128FV_HALF_BLOCK_SIZE             0x8000    /* 128 Blocks  of 32KBytes */
#define W25Q128FV_SECTOR_SIZE                 0x1000    /* 4096 sectors of 4kBytes */
#define W25Q128FV_PAGE_SIZE                   0x100     /* 65536 pages of 256 bytes */

#define W25Q128FV_DUMMY_CYCLES_READ           4
#define W25Q128FV_DUMMY_CYCLES_READ_QUAD      10

#define W25Q128FV_BULK_ERASE_MAX_TIME         250000//ms
#define W25Q128FV_SECTOR_ERASE_MAX_TIME       3000
#define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME    800

#define W25Q128FV_FLASH_ID                    0XEF4018
/*  W25Q128FV 指令  */
/* 复位操作 */
#define RESET_ENABLE_CMD                      0x66
#define RESET_MEMORY_CMD                      0x99

#define ENTER_QPI_MODE_CMD                    0x38
#define EXIT_QPI_MODE_CMD                     0xFF

/* 读取ID指令 */
#define READ_ID_CMD                           0x90
#define DUAL_READ_ID_CMD                      0x92
#define QUAD_READ_ID_CMD                      0x94
#define READ_JEDEC_ID_CMD                     0x9F

/* 读操作指令 */
#define READ_CMD                              0x03
#define FAST_READ_CMD                         0x0B
#define DUAL_OUT_FAST_READ_CMD                0x3B
#define DUAL_INOUT_FAST_READ_CMD              0xBB
#define QUAD_OUT_FAST_READ_CMD                0x6B
#define QUAD_INOUT_FAST_READ_CMD              0xEB

/* 写使能操作指令 */
#define WRITE_ENABLE_CMD                      0x06
#define WRITE_DISABLE_CMD                     0x04

/* 读写状态寄存器操作指令 */
#define READ_STATUS_REG1_CMD                  0x05
#define READ_STATUS_REG2_CMD                  0x35
#define READ_STATUS_REG3_CMD                  0x15

#define WRITE_STATUS_REG1_CMD                 0x01
#define WRITE_STATUS_REG2_CMD                 0x31
#define WRITE_STATUS_REG3_CMD                 0x11

/* 编程指令 */
#define PAGE_PROG_CMD                         0x02
#define QUAD_INPUT_PAGE_PROG_CMD              0x32

/* 擦除Flash指令 */
#define SECTOR_ERASE_CMD                      0x20
#define BLOCK_32KB_ERASE_CMD                  0x52
#define BLOCK_64KB_ERASE_CMD                  0xD8
#define CHIP_ERASE_CMD                        0xC7

#define PROG_ERASE_RESUME_CMD                 0x7A
#define PROG_ERASE_SUSPEND_CMD                0x75

/* 状态寄存器标志位 */
#define W25Q128FV_FSR_BUSY                    ((uint8_t)0x01) /* busy */
#define W25Q128FV_FSR_WREN                    ((uint8_t)0x02) /* write enable */
#define W25Q128FV_FSR_QE                      ((uint8_t)0x02) /* quad enable */

/* Flash 状态码*/
#define FLASH_OK                          ((uint8_t)0x00)
#define FLASH_ERROR                       ((uint8_t)0x01)
#define FLASH_BUSY                        ((uint8_t)0x02)
#define FLASH_NOT_SUPPORTED               ((uint8_t)0x04)
#define FLASH_SUSPENDED                   ((uint8_t)0x08)



uint32_t QSPI_W25Qx_ReadID(void);
void QSPI_W25Qx_Reset_Memory();
void QSPI_W25Qx_EraseSector(uint32_t _SectorAddr);
uint8_t QSPI_W25Qx_Write_Buffer(uint8_t *_pBuf,uint32_t _write_Addr,uint16_t _write_Size);
void QSPI_W25Qx_Read_Buffer(uint8_t *_pBuf,uint32_t _read_Addr,uint32_t _read_Size);


#endif /* BSP_QSPI_W25Q128_H_ */

bsp_qspi_w25q128.c

/*
 * bsp_quadspi_W25Q128.c
 *
 *  Created on: Apr 25, 2021
 *      Author: Administrator
 *
 *
 *
 *
 *
 */
#include <bsp_qspi_w25q128.h>


/* 仅限本文件使用的函数 */
static void QSPI_W25Qx_Write_Enable(QSPI_HandleTypeDef *hqspi);
static uint8_t QSPI_W25Qx_AutoPollingMemRead(uint32_t Timeout);
static void QSPI_W25Qx_Enter(QSPI_HandleTypeDef *hqspi);
static void QSPI_W25Qx_Exit(QSPI_HandleTypeDef *hqspi);

/**
  * 函数功能: 读取Flash状态并等待操作结束
  * 输入参数: Timeout:等待时间
 *
  * 返回值: Flash的状态
  * 说明:
 *
 *
 */
static uint8_t QSPI_W25Qx_AutoPollingMemRead(uint32_t Timeout)
{
	QSPI_CommandTypeDef     s_command={0};
    QSPI_AutoPollingTypeDef s_config={0};

    /* 基本配置 */
    s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
    s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
    s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
    s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
    s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
    s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

    /* 配置自动轮询模式 */
    s_command.Instruction       = READ_STATUS_REG1_CMD;  //读取状态寄存器
    s_command.AddressMode       = QSPI_ADDRESS_NONE;     //没有地址
    s_command.DataMode          = QSPI_DATA_1_LINE;      //1线数据
    s_command.DummyCycles       = 0;                     //无空周期

    /* 配置自动轮询寄存器(不断查询状态寄存器bit0,等待其为0) */
    s_config.Match           = 0x00;				   //等待其为0
    s_config.Mask            = W25Q128FV_FSR_BUSY;     //状态寄存器bit0
    s_config.MatchMode       = QSPI_MATCH_MODE_AND;	   //逻辑与
    s_config.StatusBytesSize = 1;
    s_config.Interval        = 0x10;
    s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;

    /* 自动轮询模式等待编程结束 */
    if(HAL_QSPI_AutoPolling(&hqspi,&s_command,&s_config,Timeout) != HAL_OK)
    {
	   user_Assert(__FILE__,__LINE__);
    }

    return FLASH_OK;

}

/**
  * 函数功能: 读取外部FLASH的ID
  * 输入参数: 无
 *
  * 返回值: uint32_t
  * 说明:
 *  1、使用SPI模式的指令
 *
 */
uint32_t QSPI_W25Qx_ReadID(void)
{
	uint32_t uiID;

	QSPI_CommandTypeDef s_command = {0};
	uint8_t buf[3];

	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 读取JEDEC ID */
	s_command.Instruction       = READ_JEDEC_ID_CMD;  //读取ID命令: 0x9F
	s_command.AddressMode       = QSPI_ADDRESS_NONE;  //没有地址
	s_command.DataMode          = QSPI_DATA_1_LINE;   //1线数据
	s_command.DummyCycles       = 0;                  //无空周期
	s_command.NbData            = 3;                  //读取三个数据

	/* 发送指令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 启动接收 */
	if(HAL_QSPI_Receive(&hqspi,buf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	uiID = (buf[0] << 16) | (buf[1] << 8) | buf[2];

	return uiID;
}

/**
  * 函数功能:  外部FLASH写使能
  * 输入参数:  hqspi  QSPI_HandleTypeDef句柄
 *
  * 返回值: 无
  * 说明:
 *  1、使用SPI模式的指令
 *
 */
static void QSPI_W25Qx_Write_Enable(QSPI_HandleTypeDef *hqspi)
{
	QSPI_CommandTypeDef s_command = {0};
	QSPI_AutoPollingTypeDef s_config={0};

	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	//s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 写入使能配置 */
	s_command.Instruction       = WRITE_ENABLE_CMD;   //写使能命令
	s_command.AddressMode       = QSPI_ADDRESS_NONE;  //没有地址
	s_command.DataMode          = QSPI_DATA_NONE;     //没有数据
	s_command.DummyCycles       = 0;                  //无空周期
	s_command.NbData            = 0;                  //空数据

	/* 发送指令 */
	if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 配置自动轮询模式等待操作完成 */
	s_config.Match           = W25Q128FV_FSR_WREN;
	s_config.Mask            = W25Q128FV_FSR_WREN;
	s_config.MatchMode       = QSPI_MATCH_MODE_AND;
	s_config.StatusBytesSize = 1;
	s_config.Interval        = 0x10;
	s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;

	s_command.Instruction = READ_STATUS_REG1_CMD;
	s_command.DataMode    = QSPI_DATA_1_LINE;
	s_command.NbData      = 1;

	if(HAL_QSPI_AutoPolling(hqspi,&s_command,&s_config,HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

}

/**
  * 函数功能:  擦除外部FLASH的扇区(大小:4KB)
  * 输入参数:  _uiSectorAddr: 扇区地址,以4KB为单位的地址,比如0,4096,8192等
 *
  * 返回值: 无
  * 说明:
 *  1、
 *
 */
void QSPI_W25Qx_EraseSector(uint32_t _SectorAddr)
{
	QSPI_CommandTypeDef	s_command = {0};

	/* 写使能 */
	QSPI_W25Qx_Write_Enable(&hqspi);

	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 擦除扇区配置 */
	s_command.Instruction       = SECTOR_ERASE_CMD;     //扇区擦除指令
	s_command.AddressMode       = QSPI_ADDRESS_1_LINE;  //1线地址方式
	s_command.DataMode          = QSPI_DATA_NONE;       //没有数据
	s_command.Address           = _SectorAddr;          //扇区的首地址,保证是4KB整数倍
	s_command.DummyCycles       = 0;                    //无空周期

	/* 发送指令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 自动轮询模式等待编程结束 */
	if(QSPI_W25Qx_AutoPollingMemRead(W25Q128FV_SUBSECTOR_ERASE_MAX_TIME) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

}

/**
  * 函数功能:  页编程,通过QSPI将数据写入外部FALSH
  * 输入参数:  _pBuf: 需要存入数据的指针
 *          _write_Addr: 目标区域首地址,即页首地址,比如0,256,512等。
 *          _write_Size: 数据个数,不能超过页的大小,可以填入(1 ~ 256)
  * 返回值: 无
  * 说明:
 *    1、华邦的W25Q128FV仅仅支持SPI模式写入
 */
uint8_t QSPI_W25Qx_Write_Buffer(uint8_t *_pBuf,uint32_t _write_Addr,uint16_t _write_Size)
{
	QSPI_CommandTypeDef	s_command = {0};

	/* 防止写入的大小超过256字节 */
	if(_write_Size > W25Q128FV_PAGE_SIZE)
	{
		/* 进入断言,提示错误 */
		user_Assert(__FILE__,__LINE__);
	}

	QSPI_W25Qx_Write_Enable(&hqspi);  //写使能

	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/*写入序列配置 */
	s_command.Instruction       = QUAD_INPUT_PAGE_PROG_CMD;   //24位四线快速写入指令
	s_command.AddressMode       = QSPI_ADDRESS_1_LINE;        //1线地址方式
	s_command.DataMode          = QSPI_DATA_4_LINES;          //4线数据方式
	s_command.Address           = _write_Addr;                //写入数据的地址
	s_command.NbData            = _write_Size;                //写入数据的大小
	s_command.DummyCycles       = 0;                          //无空周期

	/* 发送指令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 启动传输 */
	if(HAL_QSPI_Transmit(&hqspi,_pBuf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 自动轮询模式等待编程结束 */
	if(QSPI_W25Qx_AutoPollingMemRead(W25Q128FV_SUBSECTOR_ERASE_MAX_TIME) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	return 1;
}

/**
  * 函数功能:  外部FLASH芯片进入QSPI模式
  * 输入参数:  *hqspi: qspi句柄
 *
  * 返回值: 无
  * 说明:
 *
 */
static void QSPI_W25Qx_Enter(QSPI_HandleTypeDef *hqspi)
{
	QSPI_CommandTypeDef	s_command = {0};
	/* 配置FLASH进入QPSI模式 */
	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 写入序列配置 */
	s_command.Instruction       = ENTER_QPI_MODE_CMD;         //进入QSPI模式
	s_command.AddressMode       = QSPI_ADDRESS_NONE;          //无地址方式
	s_command.DataMode          = QSPI_DATA_NONE;             //无数据方式
	s_command.DummyCycles       = 0;                          //0空闲状态周期

	/* 发送指令 */
	if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

}

/**
  * 函数功能:  外部FLASH芯片退出QSPI模式
  * 输入参数:  *hqspi: qspi句柄
 *
  * 返回值: 无
  * 说明:
 *
 */
static void QSPI_W25Qx_Exit(QSPI_HandleTypeDef *hqspi)
{
	QSPI_CommandTypeDef	s_command = {0};

    /* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;	  //4线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 写入序列配置 */
	s_command.Instruction       = EXIT_QPI_MODE_CMD;         //进入QSPI模式
	s_command.AddressMode       = QSPI_ADDRESS_NONE;          //无地址方式
	s_command.DataMode          = QSPI_DATA_NONE;             //无数据方式
	s_command.DummyCycles       = 0;                          //0空闲状态周期

	/* 发送指令 */
	if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}
}

/**
  * 函数功能:  连续读取若干字节,字节的个数不能超出芯片容量
  * 输入参数:  _pBuf: 读取数据的存放地址
 *          _read_Addr: 起始的地址
 *          _read_Size: 数据个数,可以大于W25Q128FV_PAGE_SIZE,但不能超出芯片总容量
  * 返回值: 无
  * 说明:
 *    1、从SPI模式切换到QSPI模式,读取完毕后切换回SPI模式(其他函数仅仅支持SPI模式)。
 */
void QSPI_W25Qx_Read_Buffer(uint8_t *_pBuf,uint32_t _read_Addr,uint32_t _read_Size)
{
	QSPI_CommandTypeDef	s_command = {0};

	/* 进入QSPI模式 */
	QSPI_W25Qx_Enter(&hqspi);

	/* 开始从FLASH读取数据 */
	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/*读取序列配置 */
	s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;     //24位四线快速写入指令
	s_command.AddressMode       = QSPI_ADDRESS_4_LINES;       //4线地址方式
	s_command.DataMode          = QSPI_DATA_4_LINES;          //4线数据方式
	s_command.Address           = _read_Addr;                 //写入数据的地址
	s_command.NbData            = _read_Size;                 //写入数据的大小
	s_command.DummyCycles       = 2;                          //两个空闲状态周期(4个时钟周期),结合时序理解

	/* 发送指令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 读取数据 */
	if(HAL_QSPI_Receive(&hqspi,_pBuf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 退出QSPI模式 */
	QSPI_W25Qx_Exit(&hqspi);

}

/**
  * 函数功能: 复位外部Flash
  * 输入参数: 无
 *
  * 返回值: void
  * 说明:
 *
 */
void QSPI_W25Qx_Reset_Memory()
{
	QSPI_CommandTypeDef s_command = {0};

	/* 基本配置 */
	s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;	  //1线方式发送指令
	s_command.AddressSize       = QSPI_ADDRESS_24_BITS;       //24位地址
	s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;  //无交替字节
	s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;      //W25Q128FV不支持DDR模式
	s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;  //DDR模式,数据输出延迟
	s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;   //每次传输都发指令

	/* 复位使能W25x */
	s_command.Instruction       = RESET_ENABLE_CMD;   //复位使能命令
	s_command.AddressMode       = QSPI_ADDRESS_NONE;  //没有地址
	s_command.DataMode          = QSPI_DATA_NONE;     //没有数据
	s_command.DummyCycles       = 0;                  //无空周期

	/* 发送复位使能命令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 发送复位命令 */
	s_command.Instruction       = RESET_MEMORY_CMD;   //复位命令
	/* 发送复位使能命令 */
	if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

	/* 自动轮询模式等待等待完成 */
	if(QSPI_W25Qx_AutoPollingMemRead(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		user_Assert(__FILE__,__LINE__);
	}

}
    暂无数据