野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10377|回复: 6

AD+SPI+DMA提高采样率后,采集的数据不正确,望大家给与指点与提醒,谢谢

[复制链接]
发表于 2018-1-17 09:12:56 | 显示全部楼层 |阅读模式
本帖最后由 钓鱼村 于 2018-1-17 09:33 编辑

总体思路:1.使用AD7357芯片,4.2MSPS,可同时采集双通道信号,14bit的一款芯片(后附时序图),要求采集10k~500k的信号;                                   2.由STM32F429的SPI来传输AD采集到的数据,同时SPI的sck与AD芯片的时钟引脚相连,即SPI实现传输数据的同时提供AD的采样频率;
                3.通过DMA来传输SPI的ad返回值。故SPI只需要CS,SCLK,MISO;

代码下附
7357.png

遇到的麻烦:1. 当SPI的SCK设置为分频即1.4MHz时,能准确采集100KHz正弦信号。但是当分频系数取16,即sck为2.8MHz时钟,这时就不能得到准确的数据了?                 
                   2.通过设置32分频和16分频可以看出波形,16分频的sck空闲时没有像32分频空闲时那样置1,而是一个上升过程,这会不会是影响数据错误的原因呢?
                   3.会不会是sck频率变高以后,导致传输采集的AD数据中,发生了数据的覆盖或者丢失导致,输出数据不能得到原始波形呢?

         两种情况的波形如下:第一幅图是32分频的,sck和cs信号;第二幅图是16分频;






32分频.jpg
16分频.jpg
回复

使用道具 举报

 楼主| 发表于 2018-1-17 09:32:29 | 显示全部楼层

int main()
{               
        AD9833_GPIO_Init();           
        AD9833_reset();                        
        AD9833_Init(100000);        //  AD9833输出设置
        
        Debug_USART_Config();
        IO_GPIO_Init();               
        IO_Enalbel();                  

        SPIx_Init();                                                                           //SPI初始化
        GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);                       //CS置位
        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(10);                                                              //
               
          SPI_Cmd(AD_SPI, ENABLE);                                               //  spi使能
               data=SPIx_ReadWriteByte();                                         //  spi发送数据到主控   
   // while(DMA_GetFlagStatus(DMA1_Stream0,DMA_FLAG_TCIF0)==RESET ){};               
                 SPI_Cmd(AD_SPI, DISABLE);                                        //   spi使能   

           //    Delay(10);
        
                SPI_Cmd(AD_SPI, ENABLE);                                        //spi使能
                data=SPIx_ReadWriteByte();                                       // spi发送数据到主控                     
        //  while(DMA_GetFlagStatus(DMA1_Stream0,DMA_FLAG_TCIF0)==RESET ){};               
                 SPI_Cmd(AD_SPI, DISABLE);                                      //spi失能

                    Delay(120);                                                            //延时,保证时序正确

                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);             //cs置1
                    i--;
                    Delay(5);                                 
        }
/**************打印DMA传输的数据,双通道数据输出***************/
        for (j=numlength;j>1;j=j-2)
{        
                printf("%d,%d\n",ADC_ConvertedValue[j],ADC_ConvertedValue[j-1]);
                 Delay(10);  
}
}

/////////////////////////////////////////////////////////////spi的配置//////////////////////////////////////////////////////////////
#include "dsp_spi.h"
//SPI3
void SPIx_Init(void)
{   
                SPI_InitTypeDef   SPI_InitStructure;   
                GPIO_InitTypeDef  GPIO_InitStructure;   
       
               
                RCC_AHB1PeriphClockCmd(AD_SPI_SCK_GPIO_CLK|AD_SPI_MISO_GPIO_CLK|AD_SPI_MOSI_GPIO_CLK|AD_CS_GPIO_CLK, ENABLE);
               AD_SPI_CLK_INIT(AD_SPI_CLK,ENABLE);           
       
    GPIO_PinAFConfig(AD_SPI_SCK_GPIO_PORT,AD_SPI_SCK_PINSOURCE,AD_SPI_SCK_AF);   //PC10¸′óÃSPI3μÄSCLK
    GPIO_PinAFConfig(AD_SPI_MISO_GPIO_PORT,AD_SPI_MISO_PINSOURCE,AD_SPI_MISO_AF);  //PC11¸′óÃSPI3μÄMISO
   // GPIO_PinAFConfig(AD_SPI_MOSI_GPIO_PORT,AD_SPI_MOSI_PINSOURCE,AD_SPI_MOSI_AF);  //PC12¸′óÃSPI3μÄMOSI

        //  GPIO_PinAFConfig(GPIOA,AD_CS_PIN,GPIO_AF_SPI3);      //PA4 ¸′óÃSPI3μÄCS
               

                        GPIO_InitStructure.GPIO_Pin = AD_SPI_SCK_PIN;
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         
                    //  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      
                        GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;   
                        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
                GPIO_Init(AD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);  

            GPIO_InitStructure.GPIO_Pin = AD_SPI_MISO_PIN;
    GPIO_Init(AD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
                     
        GPIO_InitStructure.GPIO_Pin = AD_CS_PIN;       
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT ;         
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;              
          GPIO_InitStructure.GPIO_Speed=GPIO_Fast_Speed;         
    GPIO_Init(AD_CS_GPIO_PORT, &GPIO_InitStructure);      

    GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);       

    //
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;  //只接受模式
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                       //主模式
    SPI3->CR1|=1<<10;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;                   //每次传输16位
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                           //sck空闲时保持高电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                        //奇数边沿采样
    SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft;                               //NSSóéó2&#188;t&#187;1ê&#199;èí&#188;t&#191;&#216;&#214;&#198;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //SPI分频系数,和scK时钟频率设置
       
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;         
    SPI_InitStructure.SPI_CRCPolynomial = 7;                    
    SPI_Init(AD_SPI, &SPI_InitStructure);                                    
}   


u16 SPIx_ReadWriteByte(void)
{  
        u8 retry=0;         
                       
                while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
        {
                retry++;
                if(retry>200)
                        return 0;
        }                
                        return SPI_I2S_ReceiveData(AD_SPI);
       
}









回复 支持 反对

使用道具 举报

发表于 2018-1-17 09:34:20 | 显示全部楼层
没用过这个,帮顶
回复 支持 反对

使用道具 举报

发表于 2018-1-17 17:07:13 | 显示全部楼层
这有什么好说的, 垃圾示波器呗, 一提高就测不了了呗;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-17 17:09:25 | 显示全部楼层
qq390934605 发表于 2018-1-17 17:07
这有什么好说的, 垃圾示波器呗, 一提高就测不了了呗;

其实就算是示波器上显示不出好的波形,但是当spi的sck提高后,采样的数据是不正确的,所以问题应该不是示波器的问题
回复 支持 反对

使用道具 举报

发表于 2018-1-19 11:12:03 | 显示全部楼层
本帖最后由 qq390934605 于 2018-1-19 11:32 编辑
钓鱼村 发表于 2018-1-17 17:09
其实就算是示波器上显示不出好的波形,但是当spi的sck提高后,采样的数据是不正确的,所以问题应该不是示 ...

STM32 F103- SPI方式刷ST7735 TFT彩屏, 最高能稳定跑36MHZ 以上 , 这个完全不是你应该管的事;;
/////////////////////////////////////////;
    SPI1 -> CR1 &= ~(1<<10);     //RXONLY=0 全双工;=1 禁止输出;

    SPI1 -> CR1 |= 1<<9;      //SSM=0禁止软件从管理,=1启用软件从管理
    SPI1 -> CR1 |= 1<<8;      //SSI=0 NSS 电平无效;=1 NSS电平有效

    SPI1 -> CR1 &= ~(1<<7);      //LSBFIRST = 0 MSB先发; = 1 LSB先发;

    SPI1 -> CR1 &= ~(7<<3);      //BR =0 Fpclk/2  APB2Clock/2;
//    SPI1 -> CR1 |= 3<<3;                   //FPClock/16

    SPI1 -> CR1 |= 1<<2;         //MSTR = 0 配置为从设备; = 1 配置为主设备;
///////////////////////////////////;
;




捕获.PNG
捕获.PNG
回复 支持 反对

使用道具 举报

发表于 2018-1-19 11:18:38 | 显示全部楼层
本帖最后由 qq390934605 于 2018-1-19 11:45 编辑
钓鱼村 发表于 2018-1-17 17:09
其实就算是示波器上显示不出好的波形,但是当spi的sck提高后,采样的数据是不正确的,所以问题应该不是示 ...

显示不出来, 多半是示波器输出引脚与测量线路, 阻容值大, 影SPI的正常输出(高速通信引脚驱动能力非常小);;
高速通信下引脚的状态有两种, 一种是跳变, 一种保持;
;
跳变的时候即使用内部电源提供的能量(无法快速变化), 同时还有一个起推动作用的能量, 让引脚在跳变沿可以快速变化, 但问题是这个能量并不多;
;
既要被pCB, 线路吸收, 也要被线路的感性因素拦住, 还要被阻性因素给抹平,;
;
可能线长了,没了;引入示波器没了;pCB 线路宽了, 没了;(跑一半(一下)没了)
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-18 11:21 , Processed in 0.044377 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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