野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 15257|回复: 12

429模拟AD芯片SCLk时,频率达不到要求问题,望指教

[复制链接]
发表于 2017-10-24 12:17:37 | 显示全部楼层 |阅读模式
本帖最后由 钓鱼村 于 2017-10-24 12:17 编辑

       实验中,使用的是stm32F429为主控芯片,外置14位AD芯片,4.2MSPS,需要采集的数据为1k~1M。具体过程为:我的方式是通过定义一个变量,再通过移位GPIO_ReadInputDataBit()采集到的AD输出二进制,最后通过printf()打印这个变量。完成传输采集数据。AD芯片SCLK等几个管脚都是连接的普通GPIO口,所以采用模拟方式来读取输出的16位二进制,并通过串口打印到PC上。
         现目前的主要问题是模拟过程中,模拟过程的周期太长了大约1ms左右了,这样算下来只能采集500Hz的信号了。主要问题是出现在程序中printf()这个函数上,执行这一句时间太长了;具体程序贴下面;
请问下:
1.这个输出数据思路对吗?
2.如何解决printf()执行时间太长的问题?
3.是否有其他方式来输出数据,来避免执行printf(),提高采样频率?
  



回复

使用道具 举报

 楼主| 发表于 2017-10-24 12:17:38 | 显示全部楼层
本帖最后由 钓鱼村 于 2017-10-24 12:13 编辑

        int AD_control(void)
        {
                unsigned int data_num1=0;
                //int SDATA_A[16];
                unsigned short SDATA_A=0;
                unsigned short SDATA=0;
                unsigned short  DATA[300];
                 unsigned char data_num=0;
                        GPIO_SetBits(DEBUG_AD_CS_PORT,DEBUG_AD_CS_PIN);    //CS置1
                        GPIO_SetBits(DEBUG_AD_CLK_PORT,DEBUG_AD_CLK_PIN);  //SCLK置1
                        DELAY1(100);
                        GPIO_ResetBits(DEBUG_AD_CS_PORT,DEBUG_AD_CS_PIN);  //CS置0
                        DELAY1(100)               
               
               
        /**********************输出数据******************************/

                    for(data_num=0;data_num<16;data_num++)
    {
           SDATA=SDATA<<1;  

                            GPIO_ResetBits(DEBUG_AD_CLK_PORT,DEBUG_AD_CLK_PIN);                          //sclk置0
                                
                            SDATA_A=GPIO_ReadInputDataBit(DEBUG_AD_DA_PORT,DEBUG_AD_DA_PIN); //读取输出二进制位
                                                 SDATA=SDATA|SDATA_A;                                                                             //二进制位装入变量中

                            DELAY1(20);
                        
                            GPIO_SetBits(DEBUG_AD_CLK_PORT,DEBUG_AD_CLK_PIN);                          //sclk置1
                                    
                            DELAY1(20);
                        
   }        
                SDATA=SDATA>>1;            
          printf("%d,\n",SDATA);                          //打印变量输出二进制数据,,,??????就是此句占用了大量的时间

        }

回复 支持 反对

使用道具 举报

发表于 2017-10-24 13:52:18 | 显示全部楼层
这个AD芯片应该是用SPI或者其他固定的通讯方式的吧? 为啥要用模拟?

1、看不出你用了啥思路,按道理ADC芯片输出的是0~2的14次方的数字量,而GPIO_ReadInputDataBit()只能读取0和1,所以你是读取不了ADC芯片输出的数字量的。

2、printf()函数执行时间长,但是应该不影响你的ADC芯片采集的精度,只是有些数据你看不到而已。我没有办法解决,网上有重写的printf函数,你可以试一试

3、printf不不会影响你的采样率,实际的采样率还是那么高的,只是很多数据你看不到了。


回复 支持 反对

使用道具 举报

发表于 2017-10-24 13:52:48 | 显示全部楼层
接收到很多数据的时候再printf,例如采集完再输出
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-24 17:01:04 | 显示全部楼层
随风 发表于 2017-10-24 13:52
接收到很多数据的时候再printf,例如采集完再输出

      首先,表示感谢。        
      这是一种好的方法,试过了。效果比采集一个发送一个好很多。我是将每次采集的数据放到一个数组中,比如这个存放300个数,但是不知道为什么这个数组中的数定义不能超过500个?其实就算如此,通过这种模拟的方式也只能采集到100kHZ的信号。因为cs的周期为1us左右。
      除此之外还有更好的建议来采集比如500kHz左右的信号的方法吗,谢谢

回复 支持 反对

使用道具 举报

发表于 2017-10-25 09:40:56 | 显示全部楼层
钓鱼村 发表于 2017-10-24 17:01
首先,表示感谢。        
      这是一种好的方法,试过了。效果比采集一个发送一个好很多 ...

我做过七路18位AD的数据采集,直接用的SPI-DMA双缓存采集,用定时器使能DMA,在DMA中断中把数据整体迁移后发送信号量,触发整理数据并USB发送的任务,实现的高速AD,每秒读200K组AD测试没问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-25 10:47:27 | 显示全部楼层
tianzhen 发表于 2017-10-25 09:40
我做过七路18位AD的数据采集,直接用的SPI-DMA双缓存采集,用定时器使能DMA,在DMA中断中把数据整体迁移 ...

        谢谢提供这个思路,很可靠,会去尝试下的。现在我利用现目前的方法,勉强可以达到要求。现目前正在了解下429主频时钟方面的知识,希望通过设置不同的主频看是否能得到更快的采样率。如果不能实现的话,就按照这个方式尝试,谢谢
     
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-7 10:59:32 | 显示全部楼层
谢谢各位了,问题搞明白了。SPI+DMA方式即可。
回复 支持 反对

使用道具 举报

发表于 2017-11-11 18:54:32 | 显示全部楼层
直接把屏拆了,  配成 SRAM  模式,  用中断触发,  现成的接口, 一根多余的线也不用, 可以采集, 100ns 到 10ns 以内的数据;  

FSMC 的功能是很强 大的;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-17 17:15:32 | 显示全部楼层
tianzhen 发表于 2017-10-25 09:40
我做过七路18位AD的数据采集,直接用的SPI-DMA双缓存采集,用定时器使能DMA,在DMA中断中把数据整体迁移 ...

您好,我目前开始采用429的外置AD+SPI+DMA方式,来传输AD7357的采样数据;遇到了如下问题:
1. 当spi的sck设置为1.4MHz的时候,能够通过AD芯片采集到100KHz的正弦信号,但是当提高SCK为2.8MHz后,就不能得到正确的波形了,但是数据地销范围正常(0~16383);
2. 我在程序设计中,直接使用的SPI传输,然后使用DMA传输,没有使用到任何中断和定时器,其实也不知道中断和定时器在里面能起到什么作用?

望您给与指教,谢谢。
回复 支持 反对

使用道具 举报

发表于 2018-1-26 16:53:41 | 显示全部楼层
钓鱼村 发表于 2018-1-17 17:15
您好,我目前开始采用429的外置AD+SPI+DMA方式,来传输AD7357的采样数据;遇到了如下问题:
1. 当spi的s ...

1、不太清楚你说的正确波形是指什么波形,是SPI时钟SCK的波形还是采样信号的波形,同时需要看下AD芯片手册看能支持多高的速率SPI读取
2、在SPI+DMA做采样时,定时器主要起到采样时间间隔分布均匀的目的,减少采样点分布不均匀带来的波形失真,中断是能及时处理数据,避免数据覆盖掉帧的情况发生
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-31 10:46:02 | 显示全部楼层
tianzhen 发表于 2018-1-26 16:53
1、不太清楚你说的正确波形是指什么波形,是SPI时钟SCK的波形还是采样信号的波形,同时需要看下AD芯片手 ...

首先向您表示感谢!
1. 我采用的是标准的正弦波(频率可调)作为输入信号;
2.AD的芯片手册上表示f_sclk最高可支持80MHz,所以SPI读取的速率可参照这个速度,所以数据传输的速度能够跟上的;
3.通过您说的定时器和中断的作用,我觉得还是程序设计中的不完善造成的错误;

我先加入这些功能后看看结果如何,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-3-7 22:08:37 | 显示全部楼层
本帖最后由 钓鱼村 于 2018-3-8 08:32 编辑
tianzhen 发表于 2018-1-26 16:53
1、不太清楚你说的正确波形是指什么波形,是SPI时钟SCK的波形还是采样信号的波形,同时需要看下AD芯片手 ...

您好,前一段时间请教过您的问题,现在还没有解决,再次向您请教些问题。谢谢
总体描述:使用SPI+DMA中断方式接收AD芯片的采样100KHz的正弦信号采样数据,并在DMA中断传输完成服务函数中打印ADC_ConvertedValue[500]采样数据;
问题描述:(1)采样SPI的32分频(1.4MHz)可以恢复100KHz正弦信号,而16分频(2.8MHz)则不能恢复出完整正弦信号?(后面附上采样图)
                (2)是否是数据覆盖,或者SPI速度太快,数据未能及时处理呢?

主要程序:


  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);         //清除完成中断标志位
       }



SPI的32分频采样波形

SPI的32分频采样波形

SPI的16分频采样波形

SPI的16分频采样波形
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-12-6 06:17 , Processed in 0.050778 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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