在 main.c \ main 函数中,增加代码如下。
//系统、时钟、 IO 和 QSPI 初始化
/* USER CODE BEGIN 2 */
QSPI_CommandTypeDef sCommand;
static uint8_t Buf_ID[17] = {0};
static uint8_t TxBuf[0x10] = "Ext Flash", RxBuf[0x10] = {0};
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; //DDR 模式失能
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR 模式下,数据延迟输出
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次发送都包含命令阶段/***** 读 ID 操作 *****/
sCommand.Instruction = 0x9F; //READ ID 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
sCommand.DataMode = QSPI_DATA_1_LINE; //数据线宽
sCommand.NbData = 17; //读取数据长度。 ID 长度为 17 字节
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 0; //无 Dummy 阶段
//配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{
Error_Handler();
}
//执行 QSPI 接收
if (HAL_QSPI_Receive(&hqspi, Buf_ID,5000) != HAL_OK)
{
Error_Handler();
}
HAL_Delay(1); //延时 1ms. 单位为 SysTick 定时中断周期
/***** 写使能操作(需要在块擦除之前,使外扩存储器处于写使能状态) *****/
sCommand.Instruction = 0x06; //写使能 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 0; //无 Dummy 阶段
//配置发送命令
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{
Error_Handler();
}
/***** 块擦除操作 *****/
sCommand.Instruction = 0xD8; //扇区擦除 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽。无地址阶段
sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
sCommand.Address = 0; //位于所需擦除扇区内的任一地址。
sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 0; //无 Dummy 阶段
//配置发送命令
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{Error_Handler();
}
HAL_Delay(3000); //延时 3s. 单位为 SysTick 定时中断周期
/***** 写使能操作(需要在块擦除之前,使外扩存储器处于写使能状态) *****/
sCommand.Instruction = 0x06; //写使能 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_NONE; //地址线宽。无地址阶段
sCommand.DataMode = QSPI_DATA_NONE; //数据线宽。无数据阶段
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 0; //无 Dummy 阶段
//配置发送命令
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{
Error_Handler();
}
/***** 四线快速写操作 *****/
sCommand.Instruction = 0x32; //四线快速写 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽
sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
sCommand.Address = 0; //写入起始地址
sCommand.DataMode = QSPI_DATA_4_LINES; //数据线宽
sCommand.NbData = 10; //写入数据长度
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 0; //无 Dummy 阶段
//配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{
Error_Handler();
}
//执行 QSPI 接收
if (HAL_QSPI_Transmit(&hqspi, TxBuf ,5000) != HAL_OK)
{
Error_Handler();
}
HAL_Delay(5); //延时 5ms. 单位为 SysTick 定时中断周期
/***** 四线快速读操作 *****/
sCommand.Instruction = 0x6B; //四线快速读 命令码
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; //命令线宽
sCommand.AddressMode = QSPI_ADDRESS_1_LINE; //地址线宽
sCommand.AddressSize = QSPI_ADDRESS_24_BITS; //地址长度
sCommand.Address = 0; //起始地址
sCommand.DataMode = QSPI_DATA_4_LINES; //数据线宽sCommand.NbData = 10; //读取数据长度
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无复用字节阶段
sCommand.DummyCycles = 8; //Dummy 阶段。 N25Q128A13EF840F
Dummy cycles 默认为 15
//配置命令(在有数据阶段时,命令在后续发送/接收 API 调用时发送)
if (HAL_QSPI_Command(&hqspi, &sCommand, 5000) != HAL_OK)
{
Error_Handler();
}
//执行 QSPI 接收
if (HAL_QSPI_Receive(&hqspi, RxBuf,5000) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END 2 */
|