[应用相关] DMA的传输完成中断疑问???

[复制链接]
 楼主| 内政奇才 发表于 2021-4-9 14:46 | 显示全部楼层 |阅读模式
请问下各位:  DMA的中断完成标志位问题??
     总体描述: DMA存储来自SPI的500个数据,我检测中断传输完成标志位,然后再到中断服务函数中,打印出这500个数据;
       问题是:是DMA将500个完全缓存到内存中后,然后中断完成标志位置1,再进入中断服务函数,打印出500个数据?还是DMA接收1个数据后,就进入中断函数打印这个数据,然后循环进行直到取满500个数据呢?
程序例子如下:
         while (1)
        {                 
                GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN);        //CS置0                  
                         Delay(5);                                               
                SPI_Cmd(AD_SPI, ENABLE);                                        //SPI开启        
                       data=SPIx_ReadWriteByte();                                //产生16个周期的读取数据
                SPI_Cmd(AD_SPI, DISABLE);                                       //SPI关闭
                    Delay(140);                                                   
                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);          //CS置1
                    Delay(5);                                                                  
        }

///////////////////////////中断服务函数//////////////////////////////////
        void DMA1_Stream0_IRQHandler(void)  

       {        
                 for (j=500;j>1;j--)
              {        
                printf("%d\n",ADC_ConvertedValue[j]);
              }
               DMA_ClearITPendingBit(DMA1_Stream0,DMA_IT_TCIF0);         //清除完成中断标志位
       }

     程序调试过程中,使能SPI后,再执行  data=SPIx_ReadWriteByte();  不管你缓存的数据再多,都马上进入DMA传输完成中断服务函数。所以我疑惑,到底是采集完整个数据后进入中断服务函数,还是采集一个数据就进入中断函数。所以仿真不出来效果。


麻花油条 发表于 2021-4-9 14:47 | 显示全部楼层
DMA传输是自动触发的,不需要再在代码中显示的提供时钟信号。楼主这个传输过程不对,应该是使能DMA,并使能SPI的DMA传输请求就可以了
豌豆爹 发表于 2021-4-9 14:47 | 显示全部楼层
建议楼主在中断中设立一个标志位就退出,然后在主函数中检测标志位为1时打印500个数据后清标志位。在中断中尽量不要调用子函数,特别是打印这种慢函数。如果你在中断函数中打印500个数据,估计会与下一次中断冲突。
七毛钱 发表于 2021-4-9 14:48 | 显示全部楼层
学习了,感谢分享
海滨消消 发表于 2021-4-9 14:49 | 显示全部楼层
这个需要用到定时器了,使用pwm来驱动cs,pwm溢出事件触发dma的数据传输,这个我没试过,理论上是可行的
香水城 发表于 2021-4-10 10:09 | 显示全部楼层
应该说,你需要实现什么才决定怎么做。

如果说,你希望收到500个数据后进入DAM完成中断去打印也是可以的,DMA传输长度设置为500,你现在似乎实现不了,可能原理上哪里没理解到位。

如果你希望收一个数据打印一个数据也行,你把DMA传输长度设置为1,来一个中断一次去打印。

当然,诚如像楼上所言,采用定时器来触发DMA请求 实现数据传输也可以。此时DMA触发事件来自定时器事件。而上面的DMA触发来自于SPI通信收发事件。
别看我照片 发表于 2021-4-10 19:06 | 显示全部楼层
定时器加上PWM,就可以了。很棒的组合。
diweo 发表于 2021-4-12 16:50 | 显示全部楼层
肯定是等所有数据全部传输完之后,触发一次DMA中断。
你所观察的现象和预期不一致,估计是DMA没有正确配置。
另外,不建议在中断函数里面调用printf()。其实你只要在中断函数里面设个断点,等到触发中断的时候,到Memory窗口观察和分析一下目标地址上的数据即可。
木木guainv 发表于 2021-5-6 17:13 | 显示全部楼层
不需要这么大的缓存吧
磨砂 发表于 2021-5-6 17:14 | 显示全部楼层
想要实现什么功能呢
晓伍 发表于 2021-5-6 17:14 | 显示全部楼层
dma是自动触发的
八层楼 发表于 2021-5-6 17:15 | 显示全部楼层
不需要设置这么大的啊
观海 发表于 2021-5-6 17:16 | 显示全部楼层
小看dma了  它是自动触发的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

185

主题

1152

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部