AI8051U QSPI BUSY问题?
AI8051U QSPI读写穿行FLASH ,地址:0000000,上电擦除后写32字节后是不时死循环在 QSPI_CheckBusy();查FIFO=0;请大神帮忙看什么原因?void QSPI_READ_INSTR_SDATA(BYTE cmd, BYTE *pdat, WORD datalen)的 while (QSPI_CheckBusy());屏蔽后可正常写和读。
正常的数据
不正常数据,发完32字节数据就死循环检测忙标记,后面的05命令就没发了
/----------------------------------------------------------------------------------
void DMA_QSPI_SEND(DWORD addr)
{
while (QSPI_CheckBusy());
BLE_SEND_DATA=~BLE_SEND_DATA;
BLE_SEND_DATA=~BLE_SEND_DATA;
BLE_SEND_DATA=~BLE_SEND_DATA;
BLE_SEND_DATA=~BLE_SEND_DATA;
W25Q_DMA_PageProgram_32(addr, BLE_SEND_DATA, 32);
}
//-----------------------------------------------------------------------------------
void W25Q_DMA_PageProgram_32(DWORD addr, BYTE *pdat, WORD datalen) //BYTE
{
W25Q_WriteEnable_06();
QSPI_DMA_WRITE_INSTR_SADDR24_QDATA(0x32, addr, pdat, datalen);
W25Q_WaitBusy(100);
}
//-----------------------------------------------------------------------------------
void QSPI_DMA_WRITE_INSTR_SADDR24_QDATA(BYTE cmd, DWORD addr, BYTE *pdat, WORD datalen) //byte
{
while (QSPI_CheckBusy()); //检测忙状态
QSPI_SetWriteMode(); //写模式
QSPI_SetDataLength(datalen-1);//设置数据长度
QSPI_SetAddressSize(2); //设置地址宽度为24位(2+1字节)
QSPI_SetDummyCycles(0); //设置DUMMY时钟
QSPI_NoInstruction(); //设置无指令模式(防止误触发)
QSPI_NoAddress(); //设置无地址模式(防止误触发)
QSPI_NoAlternate(); //无间隔字节
QSPI_DataQuadMode(); //设置数据为四线模式
QSPI_SetInstruction(cmd); //设置指令
QSPI_SetAddress(addr); //设置地址
QSPI_InstructionSingMode(); //设置指令为单线模式
QSPI_AddressSingMode(); //设置地址为单线模式
QSPI_DMA_WRITE(pdat, datalen);
}
//-----------------------------------------------------------------------------------
void QSPI_DMA_WRITE(BYTE *pdat, WORD datalen)
{
/
//DMA_QSPI_ITVL=0x04;
//DMA_QSPI_ITVH=0x02;
DMA_QSPI_AMT = datalen-1; //设置DMA数据长度
DMA_QSPI_AMTH = (datalen-1) >> 8;
DMA_QSPI_TXAH = (WORD)pdat >> 8;//设置DMA的存储器起始地址
DMA_QSPI_TXAL = (BYTE)pdat; //设置DMA的存储器起始地址
DMA_QSPI_STA = 0x00; //清除DMA状态
DMA_QSPI_CFG = 0x40; //使能DMA写操作
DMA_QSPI_CR = 0xc2; //启动DMA并触发QSPI写操作
while (!(DMA_QSPI_STA & 0x01)); //等待DMA操作完成
DMA_QSPI_STA = 0x00; //清除DMA状态
DMA_QSPI_CFG = 0x00;
DMA_QSPI_CR = 0x00;
QSPI_ClearTimeout();
QSPI_ClearMatch();
QSPI_ClearError();
}
//-----------------------------------------------------------------------------------
BYTE W25Q_ReadSR1_05()
{
BYTE dat;
QSPI_READ_INSTR_SDATA(0x05, (BYTE *)&dat, 1);
return dat;
}
//-----------------------------------------------------------------------------------
void W25Q_WaitBusy(int n) //自动轮询周期时间单位: us
{
while (W25Q_ReadSR1_05() & 0x01) --n;
if (n);
// QSPI_POLLING_READ_INSTR_SDATA(0x05, 0x01, 0x00, 12*n);
}
//-----------------------------------------------------------------------------------
void QSPI_READ_INSTR_SDATA(BYTE cmd, BYTE *pdat, WORD datalen)
{
while (QSPI_CheckBusy()); //检测忙状态
QSPI_SetReadMode(); //读模式
QSPI_SetDataLength(datalen-1);//设置数据长度
QSPI_SetDummyCycles(0); //设置DUMMY时钟
QSPI_InstructionSingMode(); //设置指令为单线模式
QSPI_NoAddress(); //无地址字节
QSPI_NoAlternate(); //无间隔字节
QSPI_DataSingMode(); //设置数据为单线模式
QSPI_SetInstruction(cmd); //设置指令
while (!QSPI_CheckTransfer());//等到数据传输完成
QSPI_ClearTransfer(); //清除传输完成标志
while (datalen)
{
*pdat = QSPI_ReadData(); //从FIFO中读取数据
pdat++;
datalen--;
}
while (QSPI_CheckFIFOLevel()) //清空FIFO
QSPI_ReadData();
}
关于AI8051U QSPI BUSY问题的分析与建议如下:
根据您提供的描述,AI8051U在使用QSPI接口对W25Q系列Flash进行读写操作时,在地址0x0000000上执行擦除后写入32字节数据的过程中,出现死循环卡在QSPICheckBusy()函数中。进一步观察发现,当屏蔽该检查语句后,程序可正常运行,表明问题可能与QSPI忙状态检测机制相关。
一、可能原因分析
1. QSPI控制器状态未正确释放
在完成一次写操作后,QSPI控制器可能未及时释放“busy”标志,导致后续操作无法继续。这可能是由于DMA传输未完全完成,或QSPI内部状态机未进入空闲状态所致。
2. DMA配置不正确
若DMA配置错误(如传输长度、缓冲区地址、中断触发方式等),可能导致数据未正确写入Flash,从而引发QSPI控制器持续处于“busy”状态。
3. Flash芯片响应异常
W25Q系列Flash在接收到写指令后,会进入编程状态并返回忙状态信号(BSY)。若Flash未正确响应,或在写入过程中发生错误,可能导致QSPI控制器持续检测到“busy”。
4. QSPICheckBusy()逻辑缺陷
QSPICheckBusy()函数可能存在逻辑问题,例如未正确读取Flash的“busy”位,或读取时机不当,导致误判。
5. 时序问题
QSPI操作对时序要求较高,若主从设备之间的时钟相位、延迟设置不匹配,也可能导致Flash无法正确响应指令,进而引发“busy”状态持续。
二、排查建议
1. 验证QSPICheckBusy()实现
检查QSPICheckBusy()函数是否正确读取了Flash的“busy”状态。通常可通过发送读状态寄存器指令(如0x05)并读取返回值来判断。
c
BYTE QSPICheckBusy(void)
{
BYTE status;
QSPIWRITECMD(0x05); // 读状态寄存器指令
QSPIREADDATA(&status, 1);
return (status & 0x01); // BSY位为第0位
}
确保该函数能准确反映Flash的忙状态。
2. 检查DMA传输完整性
确认W25QDMAPageProgram32(addr, BLESENDDATA, 32)函数是否正确配置DMA通道,并确保DMA传输完成后触发相应的中断或标志位。可在DMA传输完成后添加延时或等待标志位,以确保QSPI控制器已准备好。
3. 增加调试输出
在QSPICheckBusy()前后添加调试信息(如打印当前状态寄存器值),帮助定位“busy”状态是否由Flash实际响应引起。
4. 测试其他地址或数据
尝试将写入地址改为非0x0000000位置,或写入不同大小的数据(如16字节),观察是否仍出现相同问题,以判断是否为特定地址或数据的问题。
5. 检查Flash初始化流程
确保在写入前已正确执行擦除操作,且擦除完成后Flash已恢复正常状态。某些Flash在擦除后需要一定时间恢复,若立即写入可能引发异常。
三、临时解决方案
若您暂时无法定位根本原因,可考虑以下临时措施:
在关键操作前后添加延时:例如在QSPICheckBusy()调用前后加入短延时(如1ms),以确保QSPI控制器有足够时间处理状态变化。
优化DMA传输流程:确保DMA传输完成后,QSPI控制器已释放“busy”状态后再进行下一次操作。
四、结论
综上所述,AI8051U在QSPI操作中出现死循环问题,很可能与QSPI控制器状态检测机制或Flash响应异常有关。建议优先排查QSPICheckBusy()函数的实现逻辑及DMA传输配置,并结合调试信息进一步定位问题根源。
如需进一步协助,请提供完整的QSPI驱动代码及Flash操作流程图,以便更深入分析。
[本文内容由国芯人工智能辅助生成,仅供参考]
使用这个例程试下,可使用编好的固件配合工具先测一下硬件
SPI / QSPI 编程外部串行Flash | 配合ISP软件中【工具 | 串行Flash编程器】,2/5 - QSPI/3组SPI/I2S/I2C,一线制温湿度传感器 国芯人工智能技术交流网站 - AI32位8051交流社区
ercircle 发表于 2025-8-29 12:44
使用这个例程试下,可使用编好的固件配合工具先测一下硬件
SPI / QSPI 编程外部串行Flash | 配合ISP软件中 ...
用的是芯天下的FLASH XT25F64F,FLASH工具试了没反应,自己的程序可以读到ID是没问题的。写了数据也可以读到,就是写数据有时正常,有时死循环while (QSPI_CheckBusy()); //检测忙状态 Dick_cdz 发表于 2025-8-29 16:54
用的是芯天下的FLASH XT25F64F,FLASH工具试了没反应,自己的程序可以读到ID是没问题的。写了数据也可以读 ...
这个demo读写过大量动图没问题的。
然后,没用过XT25这款FLASH,上面这个工具默认读写的是W25Q,是否支持pin2pin先替换这个型号测试完再换回去?
或者对比下qspi读写函数差异。
国芯人工智能 发表于 2025-8-29 12:33
关于AI8051U QSPI BUSY问题的分析与建议如下:
根据您提供的描述,AI8051U在使用QSPI接口对W25Q系列Flash ...
一、可能原因分析
1. QSPI控制器状态未正确释放
在完成一次写操作后,QSPI控制器可能未及时释放“busy”标志,导致后续操作无法继续。这可能是由于DMA传输未完全完成,或QSPI内部状态机未进入空闲状态所致。
问:有可能,那怎样才能释放释放“busy”标志?
2. DMA配置不正确
若DMA配置错误(如传输长度、缓冲区地址、中断触发方式等),可能导致数据未正确写入Flash,从而引发QSPI控制器持续处于“busy”状态。
答:这个可能性很少,检查过长度和地址,中断没打开,也写了中断响应处理,预防误开。而且可从FALSH读回数据,验证数据正确。
3. Flash芯片响应异常
W25Q系列Flash在接收到写指令后,会进入编程状态并返回忙状态信号(BSY)。若Flash未正确响应,或在写入过程中发生错误,可能导致QSPI控制器持续检测到“busy”。
问:这点FLASH规格书没有看到说明在IO上有BSY返回,只读状态寄器判断,如发送命令05H.
4. QSPICheckBusy()逻辑缺陷
QSPICheckBusy()函数可能存在逻辑问题,例如未正确读取Flash的“busy”位,或读取时机不当,导致误判。
答:这点一直在等待,while (QSPI_CheckBusy()); #defineQSPI_CheckBusy(QSPI_SR1 & 0x20) 或while (QSPI_SR1 & 0x20==0x20);换过几种方式
5. 时序问题
QSPI操作对时序要求较高,若主从设备之间的时钟相位、延迟设置不匹配,也可能导致Flash无法正确响应指令,进而引发“busy”状态持续。
问:可以写入,也能读回。应该没问题?
二、排查建议
1. 验证QSPICheckBusy()实现
检查QSPICheckBusy()函数是否正确读取了Flash的“busy”状态。通常可通过发送读状态寄存器指令(如0x05)并读取返回值来判断。
答:QSPICheckBusy()只是判断AI8051U的QSPI忙标记。发05是可以读回FLASH 状态
页:
[1]