我使用的QSPI不是连接内存,而是一个FTDI显示器。
我用了STM32CubeMX和atoollic TrueStudio。我包括FreeRTOS,但我还没用。
使用QuadSPI,我很难读写1、2或4个字节,在这些字节中,我会发送一个3字节的内存地址。
如果我试图读取这样的地址,它会在HAL_QSPI_Receive超时,如果我配置了
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
如果我配置
s_command.AddressMode = QSPI_ADDRESS_NONE;
信号是为了读取一个字节而产生的,但地址当然不是发送的。
为了在以后发送地址和接收字节,我用备用字节发送地址。但现在字节数可以是1或2,但不能是4,因为我会再次超时。
我的代码片段
uint8_t pData[4];
uint32_t address = REG_ID;
QspiReadData(address, 1, pData);
uint32_t v = 0x12345678;
pData[0] = v >> 24;
pData[1] = (v >> 16) & 0xff;
pData[2] = (v >> 8) & 0xff;
pData[3] = v & 0xff;
QspiWriteData(addr, 4, pData);
uint8_t QspiReadData(uint32_t address, uint32_t size, uint8_t* pData)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Initialize the read command */
s_command.InstructionMode = QSPI_INSTRUCTION_NONE;
s_command.Instruction = 0;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_32_BITS;
s_command.Address = address;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.AlternateBytes = 0;
s_command.AlternateBytesSize = 0;
s_command.DataMode = QSPI_DATA_1_LINE; // QSPI_DATA_4_LINES
s_command.DummyCycles = 0;
s_command.NbData = size;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
printf("HAL_QSPI_Command\n");
if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
/* Reception of the data */
printf("HAL_QSPI_Receive\n");
if (HAL_QSPI_Receive(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n"); // Timeout after 5000mS
return HAL_ERROR;
}
return HAL_OK;
}
/* QUADSPI init function */
void MX_QUADSPI_Init(void)
{
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 254; /* 4 QSPI Freq= 108 MHz / (1+4) = 21.6 MHz */
hqspi.Init.FifoThreshold = 1;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
hqspi.Init.FlashSize = 0;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_8_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0; // QSPI_CLOCK_MODE_0 Rising edge CPOL=0, QSPI_CLOCK_MODE_3 Falling edge CPOL=1
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&hqspi) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
uint8_t QspiWriteData(uint32_t address, uint32_t size, uint8_t* pData)
{
QSPI_CommandTypeDef s_command;
printf("Ft813QspiReadData8(%ld, %d, pData)\n", address, size);
/* Initialize the read command */
s_command.InstructionMode = QSPI_INSTRUCTION_NONE;
s_command.Instruction = 0;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = 0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
s_command.AlternateBytes = address;
s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_24_BITS;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = size;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
printf("HAL_QSPI_Command\n");
if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
/* Reception of the data */
printf("HAL_QSPI_Transmit\n");
if (HAL_QSPI_Transmit(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
return HAL_OK;
}
有什么问题吗?
GPIO管脚的配置如下,以防对sombody有帮助:
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(qspiHandle->Instance==QUADSPI)
{
/* USER CODE BEGIN QUADSPI_MspInit 0 */
/* USER CODE END QUADSPI_MspInit 0 */
/* QUADSPI clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
/**QUADSPI GPIO Configuration
PF6 ------> QUADSPI_BK1_IO3
PF7 ------> QUADSPI_BK1_IO2
PF8 ------> QUADSPI_BK1_IO0
PF9 ------> QUADSPI_BK1_IO1
PF10 ------> QUADSPI_CLK
PB10 ------> QUADSPI_BK1_NCS
*/
GPIO_InitStruct.Pin = QUADSPI_BK1_IO3_Pin|QUADSPI_BK1_IO2_Pin|QUADSPI_CLK_Pin;
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 = QUADSPI_BK1_IO0_Pin|QUADSPI_BK1_IO1_Pin;
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);
GPIO_InitStruct.Pin = QUADSPI_BK1_NCS_Pin;
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(QUADSPI_BK1_NCS_GPIO_Port, &GPIO_InitStruct);
/* QUADSPI DMA Init */
/* QUADSPI Init */
hdma_quadspi.Instance = DMA2_Stream2;
hdma_quadspi.Init.Channel = DMA_CHANNEL_11;
hdma_quadspi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_quadspi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_quadspi.Init.MemInc = DMA_MINC_ENABLE;
hdma_quadspi.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_quadspi.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_quadspi.Init.Mode = DMA_NORMAL;
hdma_quadspi.Init.Priority = DMA_PRIORITY_LOW;
hdma_quadspi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_quadspi) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(qspiHandle,hdma,hdma_quadspi);
/* QUADSPI interrupt Init */
HAL_NVIC_SetPriority(QUADSPI_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
/* USER CODE BEGIN QUADSPI_MspInit 1 */
/* USER CODE END QUADSPI_MspInit 1 */
}
}
最佳答案
hqspi.Init.FlashSize=0;错误。QuadSPI模块需要学习读写设备的存储器。换成31。它会跑的。