本帖最后由 dh2964169 于 2018-3-4 15:26 编辑 总体描述: 利用STM32F429中的SPI通信方式,来为AD7357芯片提供采样时钟,并且获取采集的数据,SPI配置为只接受模式,再加上DMA方式存储SPI获得的数据。(测试信号100KHz正弦信号,代码后面贴出来)请大家帮我看看,谢谢 问题:当SPI使用32分频(1.4MHz的sck)的时候能够采集到正确的信号,但是16分频(sck=2.8MHz)就不能采样到准确的信号? |
32分频采集100KHz正弦信号
16分频采集100KHz正弦信号
也就是说程序这边比较单纯了。
建议好好琢磨下你用的ADC端相关配置及线路,拿出相应芯片手册再研究下。
评分
查看全部评分
#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);
}
}
//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);
}
__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´«Êä
}
评分
查看全部评分
1. 不会快的,SPI的还能支持更高的通信速度,理论上DMA存取数据到缓存数组中也应该能跟得上吧(此处不敢确定);2. AD支持的最大SCLK=80MHz;
3. sclk的图像如下所示;
16分频的SCK
16分频的MISO
这个SCLK应该没有问题吧
这个以前倒是没有考虑到。我看了看,SCK和MISO长度差不多,而且较短,但是CS有些长。在程序中本来加入了delay(),所以应该不是这方面的问题。
疑虑:会不会是DMA取数据过程中发生了覆盖之类的