2014-07-16 01:33 AM
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
2014-07-16 06:33 AM
You might be able to use the Injected Mode, not something I've tried.
2014-07-16 06:49 AM
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.
2014-07-16 06:54 AM
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.
2014-07-16 08:01 AM
I am a little short on memory and can't afford to ''waste'' it like this.
2014-07-16 08:45 AM
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.
2014-07-16 12:57 PM
You can scan the sequence (of regular conversions ) of up to 16 channels.