2016-07-07 01:37 PM
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-channels2016-07-07 01:48 PM
I have provided many examples on the forum,
Critical changes in your codevolatile 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]
2016-07-08 03:21 PM
Got it working. Thanks so much for your help!