找回密码
 立即注册
查看: 527|回复: 4

DMA_SPI问题请教

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2024-11-05 09:34:19

2

主题

0

回帖

83

积分

注册会员

积分
83
发表于 2024-9-14 10:59:24 | 显示全部楼层 |阅读模式
这两天在做SPI_DMA实验时遇到个问题,
检查了代码,不知道是何原因。
请大神门看看,万分感谢。

实验箱:STC32G12K128实验箱9.62
代码:以STC32G官方库文件包中独立项目20
串口发指令通过高速SPI访问Flash芯片实例为基础修改,
修改为串口接收到十六进制指令后,操作Flash相应的操作。
再参考官方试验箱例程包62
DMA-SPI与存储器自动收发中实例,在代码中添加了DMA方式传输。
通过打开或屏蔽自己写的myW25Qxx.h中的定义W25Qxx_SPI_DMA字段
来切换使用硬件SPI方式或硬件SPI_DMA方式传输数据。
屏幕截图 2024-09-14 102125.png

问题:
当使用硬件SPI时读取数据正常;
但使用DMA方式传输时,读取数据时第一字节数据有误,需再读取一次才正确,
当更换地址后,第一次读取,第一个字节会时更换地址前读取数据的第一个字节内容,
再读取一次新地址数据,数据才会正常。

读取数据方式,串口发送十六进制数据
读命令 |              地址               |   数据大小                        
0x52        0x00  0x00  0xA0  0x00     0x00  0x05      
读取地址为0xA000开始的5个字节数据

Flash芯片中原来数据
地址           5个数据
0xA000 0xD2 ,0x32, 0xD3, 0x32, 0xD3
0xA100 0x0F ,0x22, 0x0F , 0x22, 0x0F

使用硬件SPI传输方式:
屏幕截图 2024-09-14 090054.png
接收的数据正常。

使用DMA传输时
屏幕截图 2024-09-13 092007(1).png
需发送两次命令才能读取到正确数据,每次改变地址时,第一次读取数据的第一字节会是之前地址的数据。

完整代码请见附件。
SPI_DMA访问Flash芯片.zip (498.22 KB, 下载次数: 59)





回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:239
  • 最近打卡:2025-05-02 03:42:37

22

主题

283

回帖

905

积分

高级会员

积分
905
发表于 2024-9-14 21:42:05 来自手机 | 显示全部楼层
设置读地址,然后读取数据没有错。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:239
  • 最近打卡:2025-05-02 03:42:37

22

主题

283

回帖

905

积分

高级会员

积分
905
发表于 2024-9-14 21:45:34 来自手机 | 显示全部楼层
设置地址时读取的数据是上一次设置地址的数据
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:234
  • 最近打卡:2025-05-02 08:29:31

61

主题

818

回帖

1494

积分

金牌会员

积分
1494
发表于 2024-9-15 07:12:30 | 显示全部楼层
来看看。。。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2024-11-05 09:34:19

2

主题

0

回帖

83

积分

注册会员

积分
83
发表于 2024-9-20 16:05:23 | 显示全部楼层
本帖最后由 Rock_W 于 2024-9-20 16:07 编辑

感谢各位回复。
前几日有些忙,没有查找问题原因,昨天经过多次尝试查找问题,最后再main.c中的void RX2_Check(void)函数的读数据部分读取Flash数据后加入为等待SPI_DmaFlag标志为0后,或者执行几个空操作后,接收的数据就没有问题了。在做这两个修改之前(未添加红色代码时),在执行读取数据串口打印后,再次打印了第一个字节(DmaRxBuffer[0]),发现第2次打印的数据是没有错的。我猜想是不是串口在第一次打印第一字节时(DmaRxBuffer[0]),DMA读取还没完成,所以第一字节是上次读取的数据(错误数据),当第一字节打印完成后,DMA读取才完成,所以之后的数据没有问题;这时在不执行读取数据的情况下,再打印第一字节是正确的数据。

屏幕截图 2024-09-20 154759.png

因为程序是按照试验箱例程修改过来的,但原例程没有加等待也没有问题。但原例程不是直接打印十六进制数据,经过了ASCII码转换,需要时间,足够DMA完成接收。
以上只是我个人的猜想,不知是否正确,望大神能够指正。

代码修改如下:(添加红色的代码)
void RX2_Check(void)
{
    ..........
   //*--------------------------[读数据]-------------------------------------
   else if(RX2_Buffer[0] == 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[0]);   //test
     }
  }  
   //----------------------------[读数据结束]--------------------------------*/
   ......
}

回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:49 , Processed in 0.135571 second(s), 75 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表