Rock_W 发表于 2024-9-14 10:59:24

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传输时 需发送两次命令才能读取到正确数据,每次改变地址时,第一次读取数据的第一字节会是之前地址的数据。
完整代码请见附件。





邮箱 发表于 2024-9-14 21:42:05

设置读地址,然后读取数据没有错。

邮箱 发表于 2024-9-14 21:45:34

设置地址时读取的数据是上一次设置地址的数据

zhange 发表于 2024-9-15 07:12:30

来看看。。。

Rock_W 发表于 2024-9-20 16:05:23

本帖最后由 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]
查看完整版本: DMA_SPI问题请教