DMA_SPI问题请教
这两天在做SPI_DMA实验时遇到个问题,检查了代码,不知道是何原因。请大神门看看,万分感谢。实验箱:STC32G12K128实验箱9.62
代码:以STC32G官方库文件包中独立项目20 “串口发指令通过高速SPI访问Flash芯片”实例为基础修改,修改为串口接收到十六进制指令后,操作Flash相应的操作。再参考官方试验箱例程包62”DMA-SPI与存储器自动收发”中实例,在代码中添加了DMA方式传输。通过打开或屏蔽自己写的myW25Qxx.h中的定义W25Qxx_SPI_DMA字段来切换使用硬件SPI方式或硬件SPI_DMA方式传输数据。
问题:当使用硬件SPI时读取数据正常;但使用DMA方式传输时,读取数据时第一字节数据有误,需再读取一次才正确,当更换地址后,第一次读取,第一个字节会时更换地址前读取数据的第一个字节内容,再读取一次新地址数据,数据才会正常。
读取数据方式,串口发送十六进制数据读命令 | 地址 | 数据大小 0x52 0x000x000xA00x00 0x000x05 读取地址为0xA000开始的5个字节数据
Flash芯片中原来数据地址 5个数据0xA000 :0xD2 ,0x32, 0xD3, 0x32, 0xD30xA100 :0x0F ,0x22, 0x0F , 0x22, 0x0F
使用硬件SPI传输方式: 接收的数据正常。
使用DMA传输时 需发送两次命令才能读取到正确数据,每次改变地址时,第一次读取数据的第一字节会是之前地址的数据。
完整代码请见附件。
设置读地址,然后读取数据没有错。 设置地址时读取的数据是上一次设置地址的数据 来看看。。。 本帖最后由 Rock_W 于 2024-9-20 16:07 编辑
感谢各位回复。
前几日有些忙,没有查找问题原因,昨天经过多次尝试查找问题,最后再main.c中的void RX2_Check(void)函数的读数据部分读取Flash数据后加入为等待SPI_DmaFlag标志为0后,或者执行几个空操作后,接收的数据就没有问题了。在做这两个修改之前(未添加红色代码时),在执行读取数据串口打印后,再次打印了第一个字节(DmaRxBuffer),发现第2次打印的数据是没有错的。我猜想是不是串口在第一次打印第一字节时(DmaRxBuffer),DMA读取还没完成,所以第一字节是上次读取的数据(错误数据),当第一字节打印完成后,DMA读取才完成,所以之后的数据没有问题;这时在不执行读取数据的情况下,再打印第一字节是正确的数据。
因为程序是按照试验箱例程修改过来的,但原例程没有加等待也没有问题。但原例程不是直接打印十六进制数据,经过了ASCII码转换,需要时间,足够DMA完成接收。
以上只是我个人的猜想,不知是否正确,望大神能够指正。
代码修改如下:(添加红色的代码)
void RX2_Check(void)
{
..........
//*--------------------------[读数据]-------------------------------------
else if(RX2_Buffer == Uart_com_Read && (COM2.RX_Cnt == DataHead_Size) )
{
com = 2;
j = GetDataLength();
if(j>0 && j<EE_BUF_LENGTH )
{
W25Qxx_Read_Nbytes(Flash_addr,tmp,j);
#if defined(W25Qxx_SPI_DMA)
while(SPI_DmaFlag); //测试方法1,等待完成
// for(i=0;i<10;i++) //测试方法2,添加空操作
// _nop_();
#endif
for(i=0; i<j; i++)
{
#if defined(W25Qxx_SPI_DMA)
TX2_write2buff(DmaRxBuffer);
#else
TX2_write2buff(tmp);
#endif //#if defined(W25Qxx_SPI_DMA)
}
F0 = 1;
// TX2_write2buff(DmaRxBuffer); //test
}
}
//----------------------------[读数据结束]--------------------------------*/
......
}
页:
[1]