cancel
Showing results for 
Search instead for 
Did you mean: 

ADC with DMA on different channels

lukas23
Associate II
Posted on July 16, 2014 at 10:33

I am using a F401 to read 1024 Samples with 40ksps and it works fine so I hope that the code is ok.

DMA_INIT.DMA_Channel = DMA_Channel_0;
DMA_INIT.DMA_PeripheralBaseAddr = (uint32_t)ADC1_RDR;
DMA_INIT.DMA_Memory0BaseAddr = (uint32_t)&ADC_Raw[0];
DMA_INIT.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_INIT.DMA_BufferSize = (MAX_BLOCKSIZE);
DMA_INIT.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_INIT.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_INIT.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_INIT.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_INIT.DMA_Mode = DMA_Mode_Circular;
DMA_INIT.DMA_Priority = DMA_Priority_High;
DMA_INIT.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_INIT.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_INIT.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_INIT.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream4, &DMA_INIT);
DMA_Cmd(DMA2_Stream4, ENABLE);
DMA_ITConfig(DMA2_Stream4, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ADC_COMMON.ADC_Mode = ADC_Mode_Independent;
ADC_COMMON.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_COMMON.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_COMMON.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_COMMON);
ADC_INIT.ADC_Resolution = ADC_Resolution_12b;
ADC_INIT.ADC_ScanConvMode = DISABLE;
ADC_INIT.ADC_ContinuousConvMode = DISABLE;
ADC_INIT.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_INIT.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
ADC_INIT.ADC_DataAlign = ADC_DataAlign_Right;
ADC_INIT.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_INIT);
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_3Cycles); 
//ADC1_IN9 (PB1)
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE); 
// (for testing)
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);

But now I need to monitor an additional Voltage and a Potentiometer, both with a slower sampling rate. Is there an elegant way to use the DMA to measure these 2 channels (8 times each) after the first 1024 samples Block? Or is there another solution? The F401 has only one ADC. #multichannel #dma #adc
6 REPLIES 6
Posted on July 16, 2014 at 15:33

You might be able to use the Injected Mode, not something I've tried.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lukas23
Associate II
Posted on July 16, 2014 at 15:49

I don't think that the injected mode is right for my application. I want to measure the other channels a few times (for averaging) after the main measurement, if possible without reconfiguring the ADC and DMA before each sequence.

frankmeyer9
Associate II
Posted on July 16, 2014 at 15:54

Why not sampling all channels together at maximal rate, and discard/average the 'redundant' samples ? The additional sampling and DMA transfer does effectively not impact the core.

lukas23
Associate II
Posted on July 16, 2014 at 17:01

I am a little short on memory and can't afford to ''waste'' it like this.

frankmeyer9
Associate II
Posted on July 16, 2014 at 17:45

I am a little short on memory and can't afford to ''waste'' it like this.

 

If you drop the extra samples, the only additional memory would be two half-words (uint16) for the DMA buffer.

os_kopernika
Associate II
Posted on July 16, 2014 at 21:57

You can scan the sequence (of regular conversions ) of up to 16 channels.