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

使用STM32F4主控和外置AD芯片,如何采集1MHz的信号数据呢?

[复制链接]
dh2964169 提问时间:2018-3-26 10:13 /
本帖最后由 dh2964169 于 2018-3-26 10:13 编辑

项目要求STM32(F429,180MHz)作为主控,来控制外置AD芯片采集1MHz的模拟信号,并将采集的数据传输到主控内存中。现在使用的AD芯片为AD7357,双通道,4.2MSPS,14bit,芯片时序图后附。

实验的思路:使用SPI+DMA的传输方式,提供 32位时序  和  收集采集  的数据至内存;(其中,AD芯片需要主控提供一个CS周期内32个sclk才能出数据,故采样率实际上是CS的频率)

实验主要部分代码:
int main()
{        
        //功能芯片初始化
        AD9833_GPIO_Init();            
        AD9833_reset();                     
        AD9833_Init(150000);         

        Debug_USART_Config();
        IO_GPIO_Init();               
        IO_Enalbel();                  

        SPIx_Init();                                                                                //SPI初始化
        GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                                //CS置1

        Rheostat_DMA_Mode_Config();                                                    //DMA初始化
        DMAxx_NVIC();                                                                          //中断配置
  DMA_ITConfig(RHEOSTAT_AD_DMAR_STREAM,DMA_IT_TC,ENABLE );  //DMA传输完成中断使能
        SPI_Cmd(AD_SPI, ENABLE);                                                        //SPI使能         

  SPI_I2S_DMACmd(AD_SPI,SPI_I2S_DMAReq_Tx,ENABLE);                  //SPI_DMA发送数据使能
        SPI_I2S_DMACmd(AD_SPI,SPI_I2S_DMAReq_Rx,ENABLE);            //SPI_DMA接收数据使能

        DMA_Cmd (RHEOSTAT_AD_DMAR_STREAM,ENABLE);                   //DMA使能
       while (1)
        {                 
                  SPI_DMA_Send() ;                                                           //循环使能DMA发送数据和接收数据
                  Delay(1);
        }

void SPI_DMA_Send(void)
        {
                 GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                                        //CS置0         
                  DMA_ClearFlag(RHEOSTAT_AD_DMAT_STREAM,DMA_FLAG_TCIF5);             //清除传输完成标志位
         DMA1_Stream5->NDTR=numlength1;                                                                 //重新初始化传输数目
                 DMA_Cmd (RHEOSTAT_AD_DMAT_STREAM,ENABLE);                                  //DMA使能
         while(DMA_GetFlagStatus(RHEOSTAT_AD_DMAT_STREAM,DMA_FLAG_TCIF5 )==RESET);   /传输完成标志位               
                  DMA_Cmd (RHEOSTAT_AD_DMAT_STREAM,DISABLE);                               //DMA失能
         while(SPI_GetFlagStatus(AD_SPI,SPI_FLAG_BSY)==SET);                                    //BSY标志位等待                 
                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                                           //CS置1
        }
实验中遇到的问题: 当SPI3的速度配置最高通信速率为22.5MHz,但此时AD芯片提供的实际采样频率为440KHz(理论值:22.5/32=703KHz),因为当SPI最高时,执行void SPI_DMA_Send(void)函数过程中,使实际采样频率降低(程序貌似也不能简化了),不能采集到1MHz的信号数据;
请问:
1.      请问主控(eg:STM32F429)使用哪种方式能够为AD7357提供这么高的采样频率呢?
2.      若能提供大于4MHz的采样频率,那么如何来传输采集到的数据呢?
3.      如果主控通过任何方式都不能完成,采集1MHz的模拟信号(提供4M以上的采样频率),那么有没有其他的主控能实现呢?

32个周期为在一个通道传输A,B两个通道的16bit的数据

32个周期为在一个通道传输A,B两个通道的16bit的数据
收藏 1 评论11 发布时间:2018-3-26 10:13

举报

11个回答
twodiamond 回答时间:2018-3-27 11:01:37
用CPU来做估计比较费时,也正在研究这块,期望用PWM + SPI + DMA来自动实现对ADC的采样和读取,这篇文章经验证是可以实现的:
http://bbs.16rd.com/thread-56289-1-1.html

评分

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

查看全部评分

疯de_恒 回答时间:2018-4-17 09:21:21
STM32H7可以达到4M速度采样,直接用H7做就好了。

评分

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

查看全部评分

jcx0324 回答时间:2018-4-17 10:09:01
CPU+外置ADC的成本较高, 楼上建议采用H7也是一个不错的选择,直接内部DMA采集

评分

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

查看全部评分

switcc 回答时间:2018-4-17 10:26:38
对AD精度有要求不建议用内部ADC,内部ADC精度受总线影响,特别是FMC,以太网同时工作时

评分

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

查看全部评分

聪聪 回答时间:2018-4-17 10:59:18
楼主,你SPI3挂APB1总线上(90M)二分频也是45M的时钟吧

评分

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

查看全部评分

七哥 回答时间:2018-4-17 11:10:35
本帖最后由 toofree 于 2018-4-17 14:38 编辑

用两路SPI采,一路提供时钟做主控制,另一路作为从接收。把SDATAA、SDATAB分别采两路。
傲游截图20180417110625.png


傲游截图20180417110915.png

傲游截图20180417110854.png


话说429的SPI好嚣张,45 Mbits/s
傲游截图20180417143437.png

AD7357的SPI更高,最大80M。理论上来说,429可以用45M的SPI来与AD7357通信。
傲游截图20180417143604.png

评分

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

查看全部评分

maxtch 回答时间:2018-4-17 12:00:01
这个设计挑战性很大啊。180MHz 的处理器做 1MSPS 采样率,每个采样你只有 180 个机器周期的响应时间,基本上如果要维持采样率 CPU 就不能介入;就算换成 H7 每个采样 216 个指令周期也还是够呛。由于 AD 芯片对 CS 的要求,想不要 CPU 介入都有点难。我的建议是尝试一下看看能不能一次性配置好然后只靠定时器产生触发事件,或者就是用 FPGA 来采样。

评分

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

查看全部评分

七哥 回答时间:2018-4-17 14:45:48
maxtch 发表于 2018-4-17 12:00
这个设计挑战性很大啊。180MHz 的处理器做 1MSPS 采样率,每个采样你只有 180 个机器周期的响应时间,基本 ...

能用FPGA采的话,就非常简单了。
我FPGA直接采过4路SPI接口的18位AD,1M的AD。FPGA状态机采样及SPI传输,转换的数据存到4个寄存器,传输完成给个标志位。STM32并行读取FPGA输出寄存器。
maxtch 回答时间:2018-4-17 20:42:37
toofree 发表于 2018-4-17 14:45
能用FPGA采的话,就非常简单了。
我FPGA直接采过4路SPI接口的18位AD,1M的AD。FPGA状态机采样及SPI传输, ...

我觉得这么做都恐怕会有点慢,还不如在 FPGA 里面做个 bus matrix,FPGA 一方面不断地维持 1MSPS 读采样,存到挂着的采样存储器里面,并且判断触发中断条件;另一方面允许处理器随时过来读数据。采样存储器用 FPGA 外挂 LPDDR3 或 GDDR5。
斜阳 回答时间:2018-4-17 20:58:01
maxtch 发表于 2018-4-17 20:42
我觉得这么做都恐怕会有点慢,还不如在 FPGA 里面做个 bus matrix,FPGA 一方面不断地维持 1MSPS 读采样 ...

如果不是为了记录数据,我觉的可以在FPGA上做一些前级的处理

评分

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

查看全部评分

maxtch 回答时间:2018-4-17 21:55:16
斜阳__ 发表于 2018-4-17 20:58
如果不是为了记录数据,我觉的可以在FPGA上做一些前级的处理

的确。我前面给的设计是参考了不少廉价示波器的设计思路,如果加入前级处理也无妨。或者如果不用 FPGA,可以考虑用专职流处理 DSP,譬如 ADSP-BF531 或 TMS320C6748 这种来做前级处理。专职流处理 DSP 里面的 DMA 远远要比 STM32 的高效灵活的多,可以大大减少 CPU 的干预。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版