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

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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版