(4) 编写基本SPI按字节收发的函数;
/**接收函数
* [url=home.php?mod=space&uid=247401]@brief[/url] 从QSPI存储器中读取大量数据.
* @param pData: 指向要读取的数据的指针
* @param ReadAddr: 读取起始地址
* @param Size: 要读取的数据大小
* @retval QSPI存储器状态
*/
uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
QSPI_CommandTypeDef s_command;
/* 初始化读命令 */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = READ_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = ReadAddr;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
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;
/* 配置命令 */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK){
return QSPI_ERROR;
}
/* 接收数据 */
if(HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK) {
return QSPI_ERROR;
}
return QSPI_OK;
}
发送函数
/**
* @brief 将大量数据写入QSPI存储器
* @param pData: 指向要写入数据的指针
* @param WriteAddr: 写起始地址
* @param Size: 要写入的数据大小
* @retval QSPI存储器状态
*/
uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{
QSPI_CommandTypeDef s_command;
uint32_t end_addr, current_size, current_addr;
/* 计算写入地址和页面末尾之间的大小 */
current_addr = 0;
while (current_addr <= WriteAddr) {
current_addr += W25Q128FV_PAGE_SIZE;
}
current_size = current_addr - WriteAddr;
/* 检查数据的大小是否小于页面中的剩余位置 */
if (current_size > Size) {
current_size = Size;
}
/* 初始化地址变量 */
current_addr = WriteAddr;
end_addr = WriteAddr + Size;
/* 初始化程序命令 */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* 逐页执行写入 */
do {
s_command.Address = current_addr;
s_command.NbData = current_size;
/* 启用写操作 */
if (QSPI_WriteEnable() != QSPI_OK) {
return QSPI_ERROR;
}
/* 配置命令 */
if(HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
return QSPI_ERROR;
}
/* 传输数据 */
if(HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
return QSPI_ERROR;
}
/* 配置自动轮询模式等待程序结束 */
if(QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) {
return QSPI_ERROR;
}
/* 更新下一页编程的地址和大小变量 */
current_addr += current_size;
pData += current_size;
current_size = ((current_addr + W25Q128FV_PAGE_SIZE) > end_addr) ? (end_addr-current_addr) : W25Q128FV_PAGE_SIZE;
} while (current_addr < end_addr);
return QSPI_OK;
}
|