你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

F429中提高通信速度后SPI+DMA接收AD芯片数据不对?

[复制链接]
dh2964169 提问时间:2018-3-4 15:16 /
阅读主题, 点击返回1楼
收藏 评论33 发布时间:2018-3-4 15:16
33个回答
dh2964169 回答时间:2018-3-5 14:32:22
uwyciw100 发表于 2018-3-5 10:23
请问楼主,使用的这个调试软件是什么工具?

程序用的就是KEIL5,波形用的示波器
uwyciw100 回答时间:2018-3-5 16:47:05
dh2964169 发表于 2018-3-5 14:32
程序用的就是KEIL5,波形用的示波器

这个波形工具觉得不错,哈哈
maxtch 回答时间:2018-3-5 17:03:37
dh2964169 发表于 2018-3-5 14:31
这个以前倒是没有考虑到。我看了看,SCK和MISO长度差不多,而且较短,但是CS有些长。在程序中本来加入了d ...

CS 不是高速信号,长一点无所谓,不加 delay 应该也是没有问题的。DMA 溢出是有可能,这么快的速率 DMA 缓冲区要大一点才行,这只能估算一下 DMA 用量,对照着检查代码了。
butterflyspring 回答时间:2018-3-5 17:23:44
你这个i--在while里面?你没有到DMA的接收完成中断?你最好检测两个频率下的miso和clk的区别.

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

dh2964169 回答时间:2018-3-6 10:29:05
本帖最后由 dh2964169 于 2018-3-6 10:31 编辑
butterflyspring 发表于 2018-3-5 17:23
你这个i--在while里面?你没有到DMA的接收完成中断?你最好检测两个频率下的miso和clk的区别. ...

谢谢您的关注和提醒。       确实,开始没有弄清DMA的功能,认为i=DMA缓冲区的大小,让SPI运行i次即获得data组采样数据;并且以为i--的运行不会对运行过程产生明显的影响(现在回想,这是一种麻烦的做法)。现在在您的提示下,改用了DMA传输完成进行中断。
      但是,和以前的结果一样;我贴出两种情况的代码 和 SCLK与MISO图。请帮再看看为什么还是不能在16分频采样到准确的波形呢?

一  使用 i-- 未使用中断方式
        SPIx_Init();                                                                  //SPI初始化
        GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                  //CS置1
        Rheostat_DMA_Mode_Config();                                            //DMA初始化
        MyDMA_Enable(RHEOSTAT_ADC_DMA_STREAM,numlength);  //使能DMA
        SPI_I2S_DMACmd (AD_SPI,SPI_I2S_DMAReq_Rx,ENABLE);    //SPI_DMA功能使能
        
        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);                                                                //延时时间稍长,为的是让CS=1前,关闭SPI,否则CS=1与sck有重合
                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                 //CS置1
                    i--;
                    Delay(5);                                                                  
        }

二   去掉i--,并使用DMA中断传输完成中断,在中断服务函数打印缓存数据
        SPIx_Init();                                                                                       //SPI初始化
        GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                                       //CS置1
        Rheostat_DMA_Mode_Config();                                                           //DMA初始化
        DMAxx_NVIC();                                                                                 //DMA中断配置
        DMA_ITConfig(RHEOSTAT_ADC_DMA_STREAM,DMA_IT_TC,ENABLE );   //传输完成中断使能

        MyDMA_Enable(RHEOSTAT_ADC_DMA_STREAM,numlength);                //使能DMA
        SPI_I2S_DMACmd (AD_SPI,SPI_I2S_DMAReq_Rx,ENABLE);                  //SPI_DMA功能使能
        
        while (i)
        {                 
                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);                                                                //延时时间稍长,为的是让CS=1前,关闭SPI,否则CS=1与sck有重合
                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                 //CS置1
                    Delay(5);                                                                  
        }

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

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

结果图:


使用i--情况,SCK与MISO

使用i--情况,SCK与MISO

使用DMA中断的MISO与SCK

使用DMA中断的MISO与SCK
dh2964169 回答时间:2018-3-6 10:45:15
butterflyspring 发表于 2018-3-5 17:23
你这个i--在while里面?你没有到DMA的接收完成中断?你最好检测两个频率下的miso和clk的区别. ...

再贴出两种方式的采集数据,并在EXCEL中绘制的波形图(两种情况波形都差不多,但是无法得到标准的波形)

使用i--,没有使用中断方式

使用i--,没有使用中断方式

直接while(1),使用DMA传输完成中断

直接while(1),使用DMA传输完成中断
dh2964169 回答时间:2018-3-6 15:07:29
maxtch 发表于 2018-3-5 17:03
CS 不是高速信号,长一点无所谓,不加 delay 应该也是没有问题的。DMA 溢出是有可能,这么快的速率 DMA  ...

现在只需要对100KHz的正弦信号,采取500个点,也就是DMA缓存500个数据就行了,spi的sclk才2.8MHz,DMA存取的速度很快,所以又觉得不是DMA 溢出问题,有些矛盾。请帮我在观察下,那里还有问题呢,谢谢啦
maxtch 回答时间:2018-3-6 19:51:25
dh2964169 发表于 2018-3-6 15:07
现在只需要对100KHz的正弦信号,采取500个点,也就是DMA缓存500个数据就行了,spi的sclk才2.8MHz,DMA存 ...

DMA 的溢出问题不是速度太慢 FIFO 溢出,而是分配的内存区域太小或者和别的东西重叠导致的指针溢出。500 个数据就要分配 1k 到 2k 的内存缓冲区,你给够了吗?
dh2964169 回答时间:2018-3-6 20:56:38
maxtch 发表于 2018-3-6 19:51
DMA 的溢出问题不是速度太慢 FIFO 溢出,而是分配的内存区域太小或者和别的东西重叠导致的指针溢出。500  ...

啊啊,我直接是定义了一个数组变量ADC_ConvertedValue[500],然后让DMA指向这个数组,当500个数据存入了这个数组后,再在DMA完成中断服务函数中打印出、

好像我理解的太简单了,随意定义一个数组就可以装数据了。请问下@maxtch 我该如何去解决这个,请给与指点啊,谢谢你
maxtch 回答时间:2018-3-6 21:11:50
dh2964169 发表于 2018-3-6 20:56
啊啊,我直接是定义了一个数组变量ADC_ConvertedValue[500],然后让DMA指向这个数组,当500个数据存入了 ...

我做嵌入式到现在还没用到过这么大数据流量用单片机处理的东西,到了这种数据吞吐我一般就直接上能跑 Linux 的高速 SoC 了。

DMA 的内存分配往往有特殊要求,你要看芯片手册里面是怎么描述的。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版