cancel
Showing results for 
Search instead for 
Did you mean: 

DMA Configuration for Multiple ADC Channels STM32F4

epalaima
Associate II
Posted on July 07, 2016 at 22:37

Hi, I was wondering how I would go about configuring direct memory access for multiple channels of an ADC on the STM32F4. I have each individual ADC configured for DMA access currently but only with one channel each. 

The main issue I am unsure on is where to set the peripheral base address for the 2nd channel on an ADC, as it seems if both channels were set to the same base memory address this would cause issues. I'm currently getting the memory address via:

&sharpdefine ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)

 I've included the method I use for DMA configuration below, I don't really know where to start right now so any help or advice or information on the subject in general is much appreciated. Thanks!

void ADC3_CH12_DMA_Config(void)

{

  ADC_InitTypeDef       ADC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  DMA_InitTypeDef       DMA_InitStructure;

  GPIO_InitTypeDef      GPIO_InitStructure;

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

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

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

  DMA_InitStructure.DMA_Channel = DMA_Channel_2;  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = 1;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;

  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 ADC3 Channel12 pin as analog input ******************************/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

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

  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC3 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(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel12 configuration *************************************/

  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_3Cycles); //sample time 3 cycles

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

  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

  /* Enable ADC3 DMA */

  ADC_DMACmd(ADC3, ENABLE);

  /* Enable ADC3 */

  ADC_Cmd(ADC3, ENABLE);

}

#adc #dma #!stm32f4 #adc-channels
2 REPLIES 2
Posted on July 07, 2016 at 22:48

I have provided many examples on the forum,

Critical changes in your code

volatile uint16_t ADC3ConvertedValues[3];
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC3->DR; // Register, singular, all values come from here
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValues[0];
DMA_InitStructure.DMA_BufferSize = 3; // Multiple of channels, ie 3, 30, 300, etc size of array

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// into an array
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // Multiple channels
...
ADC_InitStructure.ADC_NbrOfConversion = 3; // Number of them

...
ADC_Init(ADC3, &ADC_InitStructure);
// Enumerate channels with Rank#
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_3Cycles); //sample time 3 cycles ADC3ConvertedValues[0]
ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 2, ADC_SampleTime_3Cycles); //sample time 3 cycles ADC3ConvertedValues[1]
ADC_RegularChannelConfig(ADC3, ADC_Channel_14, 3, ADC_SampleTime_3Cycles); //sample time 3 cycles ADC3ConvertedValues[2]

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
epalaima
Associate II
Posted on July 09, 2016 at 00:21

Got it working. Thanks so much for your help!