2015-05-06 68 views
1

У меня есть контроллер STM32F4407VGT6 на плате STM32F4 Discovery. Я пытаюсь читать данные с ADC83 ADC с использованием SPI + DMA, но буфер приема DMA всегда пуст (все нули). В режиме опроса все работает нормально, но я должен прочитать одно 16-разрядное значение образца как 3x 8-битное значение SPI и использовать бит-сдвиги. Возможно, это проблема. Моя частота дискретизации составляет 48 кГц, и в течение каждого периода необходимо считывать три значения spi для получения одного образца АЦП.STM32f4 SPI DMA принимаем

-схема AD7683 синхронизации в datasheet, стр 5.

SPI Comunication на штифтах в порядке. Вот экран от анализатора: pic

Кто-нибудь знает, как это решить или где проблема?

Заранее спасибо.

Вот мой код:

#define DMAbufferSizeRx 3 
__IO uint8_t DMAbufferRx[DMAbufferSizeRx]; 

#define DMAbufferSizeTx 1 
__IO uint8_t DMAbufferTx[DMAbufferSizeTx] ; 

void DMAconfig(void) 
{ 

NVIC_InitTypeDef NVIC_InitStructure; 

/* Enable the DMA Stream IRQ Channel */ 
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream0_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 





DMA_InitTypeDef DMA_InitStructure; 

DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ; 
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ; 
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ; 
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI3->DR)); 
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
DMA_InitStructure.DMA_Priority = DMA_Priority_High; 
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 




// Configure Tx DMA 
DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; 
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &DMAbufferTx[0]; 
DMA_InitStructure.DMA_BufferSize = DMAbufferSizeTx; 
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 
DMA_Cmd(DMA1_Stream5, DISABLE); 
while (DMA1_Stream5->CR & DMA_SxCR_EN); 
DMA_Init(DMA1_Stream5, &DMA_InitStructure); 


/* Configure Rx DMA */ 
DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; 
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &DMAbufferRx[0]; 
DMA_InitStructure.DMA_BufferSize = DMAbufferSizeRx; 
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
DMA_Cmd(DMA1_Stream0, DISABLE); 
while (DMA1_Stream0->CR & DMA_SxCR_EN); 
DMA_Init(DMA1_Stream0, &DMA_InitStructure); 



DMA_ITConfig(DMA1_Stream0, DMA_IT_TC , ENABLE); //| DMA_IT_HT 

/* Enable the DMA channel */ 

DMA_ClearFlag(DMA1_Stream0, DMA_FLAG_FEIF0|DMA_FLAG_DMEIF0|DMA_FLAG_TEIF0|DMA_FLAG_HTIF0|DMA_FLAG_TCIF0); 
DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_FEIF5|DMA_FLAG_DMEIF5|DMA_FLAG_TEIF5|DMA_FLAG_HTIF5|DMA_FLAG_TCIF5); 


DMA_Cmd(DMA1_Stream0, ENABLE); // Enable the DMA SPI TX Stream 
DMA_Cmd(DMA1_Stream5, ENABLE); // Enable the DMA SPI RX Stream 


// Enable the SPI Rx/Tx DMA request 
SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE); 
SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE); 

SPI_Cmd(SPI3, ENABLE); 

} 






void DMA1_Stream0_IRQHandler(void) 
{ 
    /* Test on DMA Stream Transfer Complete interrupt */ 
    if(DMA_GetITStatus(DMA1_Stream0, DMA_IT_TCIF0)) 
    { 
    /* Clear DMA Stream Transfer Complete interrupt pending bit */ 
    DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0); 

     // here is buffer still empty.... 
    } 
} 






void SPIconfig() 
{ 

SPI_InitTypeDef SPI_InitStructure; 

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;    
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  
SPI_InitStructure.SPI_DataSize = SPI_FirstBit_MSB;  
SPI_InitStructure.SPI_CPOL  = SPI_CPOL_High;    
SPI_InitStructure.SPI_CPHA  = SPI_CPHA_2Edge;  
SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; 

SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_16; 
SPI_InitStructure.SPI_CRCPolynomial = 0; 

SPI_Init(SPI3, &SPI_InitStructure);       
SPI_CalculateCRC(SPI3, DISABLE);       
SPI_Cmd(SPI3,ENABLE);      
} 




void RCCenable(void) 
{ 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); 
} 






void GPIOconfig(void) 
{ 

GPIO_InitTypeDef GPIO_InitDef; 

GPIO_InitDef.GPIO_Pin = REG_ON_OFF | ADC_DRIVER_ON_OFF | GPIO_Pin_6; 
GPIO_InitDef.GPIO_OType = GPIO_OType_PP; 
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_Init(GPIOE, &GPIO_InitDef); 



GPIO_InitTypeDef GPIO_InitStructure; 

GPIO_InitStructure.GPIO_Pin = SDATA | MOSI | SCLK; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_Init(GPIOB, &GPIO_InitStructure); 

GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI3); 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_SPI3); 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI3); 



GPIO_InitStructure.GPIO_Pin = CS; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_Init(GPIOD, &GPIO_InitStructure); 

GPIO_SetBits(GPIOD,CS); 
} 




void TIM2_IRQHandler(void) 
{ 
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
    { 
     TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 

     GPIO_ToggleBits(GPIOD,CS); 

    } 
} 



void TIM2_Config(void) 
{ 
NVIC_InitTypeDef NVIC_InitStructure; 

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 

TIM_TimeBaseStructure.TIM_Period = 875; 
TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 

TIM_Cmd(TIM2, ENABLE); 
} 

ответ

0

Мы используем AD7685 вместе с STM32F427ZGT (только в программном режиме без DMA). Но у нас также была проблема с общением с чипом. Проблемы были решены с этими параметрами:

hspix.Init.Direction = SPI_DIRECTION_2LINES; 
hspix.Init.DataSize = SPI_DATASIZE_16BIT; 
GPIO_InitStruct.Pull = GPIO_PULLUP; 

Конечно, размер HAL_SPI_Receive только 1, в настоящее время.

Надеюсь, что это поможет в некотором роде.

С уважением

1

Похоже, вы инициализировать DMA_Mode, DMA_MemoryDataSize и DMA_MemoryInc поля дважды. Это бесполезно - сохраняется только последнее замечание.

Также ваш DMA_PeripheralDataSize не соответствует DMA_MemoryDataSize, когда это необходимо.

Вы не подключили основную функцию, поэтому я не вижу порядок вызова функций функций init. DMAconfig() должен называться раньше, чем SPIconfig().

Существует следующая ошибка при SPIconfig:

1) Я думаю, вы догадываетесь, что вы должны исправить.

SPI_InitStructure.SPI_DataSize = SPI_FirstBit_MSB; 

2) Изменение

SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft | 
SPI_NSSInternalSoft_Set; 

в

SPI_init.SPI_NSS = SPI_NSS_Soft; 

И в конечном итоге инициализируется так:

SPI_Init(SPI3, &SPI_init); 
SPI_SSOutputCmd(SPI3, ENABLE); //!!!! 
SPI_Cmd(SPI3, ENABLE); 
SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSSInternalSoft_Set); //!!!! 
SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE); 

Надеется, что это поможет, если вы не решили ваш проблема еще.

 Смежные вопросы

  • Нет связанных вопросов^_^