板子
单片机:STM32F446
PSRAM: APS6404L (PageSize=1024Bytes)
硬件接线
PB2: QSPI_CLK 6
PC11: QSPI_NCS 1
PE7: QSPI_IO0 5
PE8: QSPI_IO1 2
PE9: QSPI_IO2 3
PE10: QSPI_IO3 7
软件环境
HAL库
问题:
1: 能通信上,但QPI模式只能工作在2线数据, 4线数据则数据不正确
2: 写入后立即读出同一地址的数据没问题;但往前读则读到的数据是最后写入的数据
猜测是Page的机制问题,如何跨页读取?
初始化代码:
int QSPI_PSRAM_Init(void)
{
QSPIHandle.Instance = QUADSPI;
QSPIHandle.Init.ClockPrescaler = 2;
QSPIHandle.Init.FifoThreshold = 4;
QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
QSPIHandle.Init.FlashSize = 22;//64Mbits=8Mbtye=2^23.size取22。
QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
QSPIHandle.Init.FlashID = QSPI_FLASH_ID_2;
QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE; //禁止双闪存模式
if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
{
return PSRAM_ERR_INIT;
}
QSPI_PSRAM_Resetenable(&QSPIHandle);
QSPI_PSRAM_Reset(&QSPIHandle);
HAL_Delay(1);
return PSRAM_OK;
}
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
//static DMA_HandleTypeDef hdma;
if(hqspi->Instance==QUADSPI)
{
/* USER CODE END QUADSPI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
/* Reset the QuadSPI memory interface */
__HAL_RCC_QSPI_FORCE_RESET();
__HAL_RCC_QSPI_RELEASE_RESET();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/* Enable DMA clock */
QSPI_DMA_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
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
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_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QSPI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QSPI;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN QUADSPI_MspInit 1 */
/* USER CODE END QUADSPI_MspInit 1 */
HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
//中断使能
//__HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TC);
}
}
读写代码
int QSPI_PSRAM_ReadPage(QSPI_HandleTypeDef *hQspi,uint8_t *pData,uint32_t FirstAddr, uint32_t BufSize)
{
QSPI_Send_CMD(hQspi,PSRAM_CMD_READ_QUAD,FirstAddr,PSRAM_QPI_READ_DUMCYCLES,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_1_LINE,QSPI_ADDRESS_24_BITS,QSPI_DATA_2_LINES,BufSize);
return _Read(hQspi,pData);
}
int QSPI_PSRAM_WritePage(QSPI_HandleTypeDef *hQspi,uint8_t *pData,uint32_t FirstAddr, uint32_t BufSize)
{
QSPI_Send_CMD(hQspi,PSRAM_CMD_WRITE_QUAD,FirstAddr,PSRAM_QPI_WRITE_DUMCYCLES,QSPI_INSTRUCTION_4_LINES,QSPI_ADDRESS_1_LINE,QSPI_ADDRESS_24_BITS,QSPI_DATA_2_LINES,BufSize);
hQspi->Instance->DLR = BufSize-1;
return _Write(hQspi,pData);
}
测试代码:
这样读写是成功的:
for (i=0; i<8; i++)
{
memset(temp,i%0xff,1024);
r1 = QSPI_PSRAM_WritePage(&QSPIHandle,(uint8_t*)temp,i*1024,1024);
memset(temp, 0, 1024);
r1 = QSPI_PSRAM_ReadPage(&QSPIHandle,(uint8_t*)temp, i*1024, 1024);
//测试发现:写1块立即读该块,都是成功的!
if (temp[123]!=(i%0xff))
{
e++;
printf("err:%d times, i=%d -->",e, i); //只要不打这个就是好的
}
}
这样写,再读,读到的数据就总是最后写入的数据:
//写入:
for (i=0; i<8; i++)
{
memset(temp,i%0xff,1024);
QSPI_PSRAM_WritePage(&QSPIHandle,(uint8_t*)temp,i*1024,1024);
}
//读出:
for (i=0; i<8; i++)
{
memset(temp, 0, 1024);
QSPI_PSRAM_ReadPage(&QSPIHandle,(uint8_t*)temp, i*1024, 1024);
if (temp[30]!=(i%0xff))
{
printf("%4d: ",i*1024);
ShowBuffer(temp,32);
}
}
离线
写入暂时没问题。主要是读出。
比如连续写了 1.2.3.4.5 共5页。
然后再回读第1页, 发现第1页是第5页的内容。
但如果 写1读1,写2读2,写5读5. 这样操作则数据都是正确的
离线
从这个文件看来,PSRAM只需要不在同一次CS中,即可任意换页。
而我的设置,采用的是MCU自己产生的CS信号,量了下波形也是每次发命令就发的CS。
所以应该是可以换页的。不知何故。。。
离线