前言
本文程序运行于STM32L452CEUX系列单片机(适用于L4),使用MDK5.33、STM32CubeMX,实现QSPI通过DMA四线读写W25Q64或128JV。
参考资料:
- STM32L4X2用户手册RM0394
- W25Q64JV数据手册
- 安富莱V7开发板用户手册
- ST官方例程(STM32Cube_FW_L4_V1.16.0\Projects\32L496GDISCOVERY\Examples\QSPI)
STM32 CubeMX配置
-
QSPI 外设配置
2^23 = 8MB(25Q64), 2^24 = 16MB(25Q128)。L452仅有一个Bank。
-
QSPI DMA配置
-
中断配置
-
时钟配置
API
W25QXX命令
用到的命令如下:
/* For W25Q64JV or W25Q128JV */
#define WRITE_STATUS_CFG_REG_CMD (0x01)
#define WRITE_ENABLE_CMD (0x06)
#define READ_ID_CMD2 (0x9F)
#define READ_STATUS_REG_CMD (0x05)
#define QUAD_INOUT_FAST_READ_CMD (0xEB)
#define QUAD_IN_FAST_PROG_CMD (0x32)
#define SUBSECTOR_ERASE_CMD (0x20)
读
W25Q64JV数据手册中的描述如下:
左上角的(1-4-4)表示指令阶段使用 1 个 IO,地址阶段使用 4 个 IO,数据阶段也是使用 4 个 IO
void QSPI_ReadBuffer(uint8_t * _pBuf, uint32_t _uiReadAddr, uint32_t _uiSize)
{
uint8_t cnt = 0;
QSPI_CommandTypeDef sCommand = {
0};
/* 基本配置 */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; /* 1 线方式发送指令 */
sCommand.AddressSize = QSPI_ADDRESS_24_BITS; /* 24 位地址 */
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; /* 无交替字节 */
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; /* W25Q64JV 不支持 DDR */
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; /* DDR 模式,数据输出延迟 */
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* 每次传输要发指令 */
/* 读取数据 */
sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; /* 24bit 地址的 4 线快速读取命令 */
sCommand.DummyCycles = 6; /* 空周期 */
sCommand.AddressMode = QSPI_ADDRESS_4_LINES; /* 4 线地址 */
sCommand.DataMode = QSPI_DATA_4_LINES; /* 4 线数据 */
sCommand.NbData = _uiSize; /* 读取的数据大小 */
sCommand.Address = _uiReadAddr; /* 读取数据的起始地址 */
if (HAL_QSPI_Command(&hqspi, &sCommand, 10000) != HAL_OK)
{
Error_Handler();
}
/* 读取 */
qspi_RxCplt = 0;
if (HAL_QSPI_Receive_DMA(&hqspi, _pBuf