AnsweredAssumed Answered

STM32F4 ADCs Can Achieve 2.4MSPS?

Question asked by Bull.Harvey on Oct 2, 2014
Latest reply on Oct 3, 2014 by Bull.Harvey

Hi,
I’m running a single ADC in continuous mode with fADC = 21MHz and expect it to provide 1.4MSPS. I seem to be getting only 0.55MSPS. Can anybody explain why this might be?

According to the STM32F407xx Datasheet (D022152, Rev 4), each of the three ADCs on the STM32F4 Discovery board should be able to take 12-bit samples at a rate of 2.4MSPS when fADC is at its maximum value of 36MHz. This figure ties up with 15 ADC cycles being used for each sample (sample time = 3 cycles + 12 for the 12-bit conversion).

I’m using the same sampling strategy, just with a lower fADC clock speed so I can ‘t see how the chip is supposed to be driven to provide the quoted conversion rates. I know that I could use triple-interleaved mode to get the speed up however I’m fairly new to this area of software and would just like to understand what’s going on. Can anybody help?

Clock Setup: I’m using the 8MHz external crystal on the Discovery board and have attached “system_stm32f4xx.c” for reference. In “stm32f4xx.h” I have changed HSE_VALUE to 8000000. I have confirmed that the period of PCLK1 is as expected (42MHz) as I am using a timer to trigger DAC output and have confirmed with a 'scope the time between updates.

ADC samples seen: I’m using DMA to write the samples into a 32 element circular buffer, then examining the contents with the Crossworks debugger (allowing it to read the contents and then stopping it). The ADC input is a 50kHz sinewave. At 1.2MSPS I should see 28 samples for each period of the sinewave but I see only 11.

ADC Setup Code:

 

#define ADC_BUFFER_SIZE   32

 

/* You can monitor the converted value by adding the variable "ADC3ConvertedValue"

   to the debugger watch window */

__IO uint16_t ADC1Buffer1[ADC_BUFFER_SIZE];

 

 

/**

  * @brief  ADC1 channel10 with DMA configuration

  * @param  None

  * @retval None

  */

void ADC1_CH10_DMA_Config(void)

{

  ADC_InitTypeDef       ADC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  DMA_InitTypeDef       DMA_InitStructure;

  GPIO_InitTypeDef      GPIO_InitStructure;

 

  /* Enable ADC1, DMA2 and GPIO clocks ****************************************/

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

 

  /* DMA2 Stream0 channel0 configuration **************************************/

  DMA_InitStructure.DMA_Channel = DMA_Channel_0; 

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1Buffer1;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE;

  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_MemoryDataSize_HalfWord;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;        

  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

  DMA_Init(DMA2_Stream0, &DMA_InitStructure);

  DMA_Cmd(DMA2_Stream0, ENABLE);

 

  /* Configure ADC1 Channel10 pin as analog input ******************************/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

 

  /* ADC Common Init **********************************************************/

  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;  // Min value = Div2

  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;  // Min value = 5Cycles

  ADC_CommonInit(&ADC_CommonInitStructure);

 

  /* ADC1 Init ****************************************************************/

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

  ADC_InitStructure.ADC_ScanConvMode = DISABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = 1;

  ADC_Init(ADC1, &ADC_InitStructure);

 

  /* ADC1 regular channel10 configuration *************************************/

  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

 

 /* Enable DMA request after last transfer (Single-ADC mode) */

  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

 

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

 

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

}

 

Attachments

Outcomes