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

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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版