|
本帖最后由 coolaimcu 于 2025-5-7 16:04 编辑
我的STM32H7B0 外挂QSPI Flash(W25Q128JV), 在测试flash的时候,擦除扇区总是失败,但是读取ID是正常的。
代码是参考的论坛上STM32H723/7B3的W25Q64JV改过来的。
现在有一个问题,非常奇怪,我调用函数W25Q128_OSPI_flash_test(void)进行测试的时,串口打印出擦除失败,W25Q128_OSPI_test_flag的值居然是254!
可是char W25Q128_OSPI_BlockErase32K(unsigned int SectorAddr)函数的返回值明明只有-2,-3,0这几个值啊,不明白怎么会返回254的??
代码如下:
#define W25Q128_OSPI_OK 0
/* 32K扇区擦除测试函数 ,在main中调用 */
char W25Q128_OSPI_flash_test(void)
{
char W25Q128_OSPI_test_flag;
unsigned int W25Q128_TestAddr = 0;
W25Q128_OSPI_test_flag = W25Q128_OSPI_BlockErase32K(W25Q128_TestAddr); //擦除32KB
if(W25Q128_OSPI_test_flag == W25Q128_OSPI_OK)
{
printf("\r\nW25Q128 flash 扇区擦除成功!!\r\n");
}
else
{
printf("\r\nW25Q128 flash 扇区擦除失败!!!! 错误代码:%d\r\n",W25Q128_OSPI_test_flag)
while (1);
}
}
/* 按block擦除,一次擦除32K */
char W25Q128_OSPI_BlockErase32K(unsigned int SectorAddr)
{
OSPI_RegularCmdTypeDef sCommand; // OSPI传输配置
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; // 通用配置
sCommand.FlashId = HAL_OSPI_FLASH_ID_1; // flash ID
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; // 1线指令模式
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; // 指令长度8位
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; // 禁止指令DTR模式
sCommand.Address = SectorAddr; // 地址
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; // 1线地址模式
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; // 地址长度24位
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; // 禁止地址DTR模式
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; // 无交替字节
sCommand.DataMode = HAL_OSPI_DATA_NONE; // 无数据模式
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; // 禁止数据DTR模式
sCommand.DummyCycles = 0; // 空周期个数
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; // 不使用DQS
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; // 每次传输数据都发送指令
sCommand.Instruction = W25Q128_CMD_BLOCKERASE_32K; // 块擦除指令,每次擦除32K字节
// 发送写使能
if (W25Q128_OSPI_WriteEnable() != W25Q128_OSPI_OK)
{
return (-2); // 写使能失败
}
// 发送擦除指令
if (HAL_OSPI_Command(&_hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return (-3); // 轮询等待无响应
}
// 使用自动轮询标志位,等待擦除的结束
if (W25Q128_OSPI_AutoPollingMemReady() != W25Q128_OSPI_OK)
{
return (-3); // 轮询等待无响应
}
return W25Q128_OSPI_OK; // 擦除成功
}
|
|