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

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

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

总体描述:      利用STM32F429中的SPI通信方式,来为AD7357芯片提供采样时钟,并且获取采集的数据,SPI配置为只接受模式,再加上DMA方式存储SPI获得的数据。(测试信号100KHz正弦信号,代码后面贴出来)请大家帮我看看,谢谢
问题:当SPI使用32分频(1.4MHz的sck)的时候能够采集到正确的信号,但是16分频(sck=2.8MHz)就不能采样到准确的信号?




32分频采集100KHz正弦信号

32分频采集100KHz正弦信号

16分频采集100KHz正弦信号

16分频采集100KHz正弦信号
收藏 评论33 发布时间:2018-3-4 15:16

举报

33个回答
xmshao 回答时间:2018-3-12 16:15:42
dh2964169 发表于 2018-3-9 00:54
只有dma传输完成标志位中断,并设置了一个中断服务函数,来打印得到的500个采样数据;请指教不足的地方, ...

也就是说程序这边比较单纯了。
建议好好琢磨下你用的ADC端相关配置及线路,拿出相应芯片手册再研究下。
butterflyspring 回答时间:2018-3-5 17:23:44
你这个i--在while里面?你没有到DMA的接收完成中断?你最好检测两个频率下的miso和clk的区别.

评分

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

查看全部评分

dh2964169 回答时间:2018-3-4 15:22:53
//////////////////////主函数//////////////////////////////
#include "stm32f4xx.h"
#include "ad9833.h"
#include "bsp_debug_usart.h"
#include "dsp_dma.h"
#include "dsp_spi.h"

extern __IO uint16_t ADC_ConvertedValue[numlength];
extern __IO uint16_t ADC_ConvertedValue1[numlength];
u16  data;
float   ADC_Vol_A;   
float   ADC_Vol_B;
float   ADC_ConvertedValue_A;
float   ADC_ConvertedValue_B;
int i=numlength,j=numlength;
       
static void Delay(__IO uint32_t nCount)       
{
        for(; nCount != 0; nCount--);
}

int main()
{               
        AD9833_GPIO_Init();            
        AD9833_reset();                          
        AD9833_Init(100000);         
       
        Debug_USART_Config();
        printf("SPI+DMA实验\n");
        IO_GPIO_Init();            
        IO_Enalbel();               

  SPIx_Init();              
        GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);          
       
        Rheostat_DMA_Mode_Config();                       //初始化
        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();                   
               SPI_Cmd(AD_SPI, DISABLE);                 //SPI关闭

                    Delay(140);                                 
                GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN);              //CS置1
                    i--;
                    Delay(5);                        
        }
        for (j=numlength;j>1;j=j-1)
{       
                printf("%d\n",ADC_ConvertedValue[j]);
                 Delay(10);  
}
}




dh2964169 回答时间:2018-3-4 15:24:55
#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);             //SPIʱÖÓʹÄÜ
       
    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_InitStructure.GPIO_Pin = AD_SPI_SCK_PIN;
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         //¸´ÓÃ
                        GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;     //50MHz
                        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;         //SCK¿ÕÏÐÉèÖÃΪ¸ßµçƽ£¬¹ÊΪÉÏÀ­
                GPIO_Init(AD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);  //³õʼ»¯PC10

            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;                   //ģʽѡÔñ;Ö÷¿Ø·¢³öSCLKÐźÅ

    SPI3->CR1|=1<<10;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;              //ÉèÖÃSPIµÄÊý¾Ý´óС
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                     //´®ÐÐͬ²½Ê±ÖӵĿÕÏÐ״̬
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                    //´®ÐÐͬ²½Ê±ÖÓ²ÉÑù±ßÑØ
    SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft;                      //NSSÓÉÓ²¼þ»¹ÊÇÈí¼þ¿ØÖÆ
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //·ÖƵϵÊý
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;              //¸ßλÓÐЧ
    SPI_InitStructure.SPI_CRCPolynomial = 7;                        //CRCУÑé
    SPI_Init(AD_SPI, &SPI_InitStructure);                           //SPI³õʼ»¯
                 

}   

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);
       
}




dh2964169 回答时间:2018-3-4 15:25:44
#include "dsp_dma.h"

__IO uint16_t ADC_ConvertedValue[numlength];
__IO uint16_t ADC_ConvertedValue1[numlength];

void Rheostat_DMA_Mode_Config(void)
{

  DMA_InitTypeDef  DMA_InitStructure;                           
        RCC_AHB1PeriphClockCmd(RHEOSTAT_ADC_DMA_CLK,ENABLE);         
  DMA_InitStructure.DMA_Channel = RHEOSTAT_ADC_DMA_CHANNEL;              //ͨµÀÑ¡Ôñ
  DMA_InitStructure.DMA_PeripheralBaseAddr = RHEOSTAT_SPI_DR_ADDR;       //DMAÍâÉèµØÖ·
  DMA_InitStructure.DMA_Memory0BaseAddr =  (u32)ADC_ConvertedValue;      //DMA´æ´¢Æ÷µØÖ·
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                //ÍâÉèµ½´æ´¢Æ÷ģʽ
  DMA_InitStructure.DMA_BufferSize = numlength;                          //Êý¾Ý´«ÊäÁ¿
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       //ÍâÉè·ÇÔöÁ¿Ä£Ê½
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                //´æ´¢Æ÷ÔöÁ¿Ä£Ê½
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//ÍâÉèÊý¾Ý´«Êä볤¶È
  DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;//´æ´¢Æ÷Êý¾Ý³¤¶È
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                          //ʹÓÃÆÕͨģʽ£¬Ò»´Î´æ´¢
  //²»Ê¹ÓÃÑ­»·Ä£Ê½ÊÇÒòΪAD²ÉÑùµÄËÙÂʸßÓÚÊý¾Ý·¢Ë͵ÄËٶȣ¬±ÜÃ⸲¸ÇÊý¾Ý
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                //ÖеÈÓÅÏȼ¶
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;            //´æ´¢Æ÷Í»·¢µ¥´Î´«Êä
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;    //ÍâÉèÍ»·¢µ¥´Î´«Êä

  DMA_Init(RHEOSTAT_ADC_DMA_STREAM, &DMA_InitStructure);                 //³õʼ»¯DMA Stream  
       
}

void MyDMA_Enable(DMA_Stream_TypeDef *DMA_streamx,u16 ndtr)
        {
          DMA_Cmd(DMA_streamx ,DISABLE );                                      //¹Ø±ÕDMA
                while(DMA_GetCmdStatus (DMA_streamx )!=DISABLE ){}                   //È·±£DMA¿ÉÒÔ±»ÉèÖÃ
                DMA_Cmd (DMA_streamx,ENABLE);                                        //¿ªÆôDMA´«Êä
        }


maxtch 回答时间:2018-3-4 20:16:35
是不是太快了?示波器检查一下 SCLK 频率,然后对照一下 ADC 芯片手册上记载的最大频率。另外,这么快的信号要注意射频传输线效应。

评分

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

查看全部评分

dh2964169 回答时间:2018-3-4 20:46:52
maxtch 发表于 2018-3-4 20:16
是不是太快了?示波器检查一下 SCLK 频率,然后对照一下 ADC 芯片手册上记载的最大频率。另外,这么快的信 ...

1.  不会快的,SPI的还能支持更高的通信速度,理论上DMA存取数据到缓存数组中也应该能跟得上吧(此处不敢确定);2.  AD支持的最大SCLK=80MHz;
3.  sclk的图像如下所示;



16分频的SCK

16分频的SCK

16分频的MISO

16分频的MISO
dh2964169 回答时间:2018-3-4 21:04:28
dh2964169 发表于 2018-3-4 20:46
1.  不会快的,SPI的还能支持更高的通信速度,理论上DMA存取数据到缓存数组中也应该能跟得上吧(此处不敢 ...

这个SCLK应该没有问题吧
uwyciw100 回答时间:2018-3-5 10:23:08
请问楼主,使用的这个调试软件是什么工具?
maxtch 回答时间:2018-3-5 12:28:03
板子上这 SPI 的三个高速信号有没有做等长线处理?如果 SCK 的长度和 MISO、MOSI 差的太多,在这么快的速度下也是会有问题的。别忘了光速有限。
dh2964169 回答时间:2018-3-5 14:31:37
maxtch 发表于 2018-3-5 12:28
板子上这 SPI 的三个高速信号有没有做等长线处理?如果 SCK 的长度和 MISO、MOSI 差的太多,在这么快的速度 ...

这个以前倒是没有考虑到。我看了看,SCK和MISO长度差不多,而且较短,但是CS有些长。在程序中本来加入了delay(),所以应该不是这方面的问题。

疑虑:会不会是DMA取数据过程中发生了覆盖之类的
1234下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版