Skip to main content
lukas23
Associate
July 16, 2014
Question

ADC with DMA on different channels

  • July 16, 2014
  • 6 replies
  • 1304 views
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
This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
July 16, 2014
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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
lukas23
lukas23Author
Associate
July 16, 2014
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 III
July 16, 2014
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
lukas23Author
Associate
July 16, 2014
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 III
July 16, 2014
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
Visitor II
July 16, 2014
Posted on July 16, 2014 at 21:57

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