cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f401re: Buffer of adc using dma is not in the order in which I have expected

t_shibata
Associate
Posted on November 08, 2015 at 16:11

Hi all.

Buffer of adc using dma is not in the order in which I have expected. I had expected that buffer is filled with channel order. However, it is not arranged in the channel order. Would someone tell me repair method? ※My device is STM32F401(Nucleo board). ※ I am not good at English. ※result example buffer[0] = ch 2 value buffer[1] = ch 3 value buffer[2] = ch 1 value buffer[3] = ch 2 value buffer[4] = ch 3 value buffer[5] = ch 1 value buffer[6] = ch 2 value buffer[7] = ch 3 value buffer[8] = ch 3 value buffer[9] = ch 1 value buffer[10] = ch 2 value buffer[11] = ch 1 value buffer[12] = ch 3 value buffer[13] = ch 2 value buffer[14] = ch 2 value buffer[15] = ch 2 value buffer[16] = ch 2 value Best regards!

enum{ ADC_BUFFER_LENGTH = 8192 };
DMA_HandleTypeDef hdma_adc1;
ADC_HandleTypeDef hadc1;
uint32_t g_MeasurementNumber;
DMA_HandleTypeDef hdma_adc1;
void DMA2_Stream0_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_adc1);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
g_MeasurementNumber += ADC_BUFFER_LENGTH;
}
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION12b;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = EOC_SEQ_CONV;
HAL_ADC_Init(&hadc1);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
ADC_MultiModeTypeDef multi;
multi.Mode = ADC_MODE_INDEPENDENT;
multi.DMAAccessMode = ADC_DMAACCESSMODE_DISABLED;
multi.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multi);
}
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
/* System interrupt init*/
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hadc->Instance==ADC1)
{
/* Peripheral clock enable */
__ADC1_CLK_ENABLE();
/**ADC1 GPIO Configuration 
PC0 ------> ADC1_IN10
PC1 ------> ADC1_IN11
PA0-WKUP ------> ADC1_IN0
PA1 ------> ADC1_IN1
PA4 ------> ADC1_IN4
PB0 ------> ADC1_IN8
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_adc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_adc1.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_adc1.Init.PeriphBurst = DMA_MBURST_SINGLE;
HAL_DMA_Init(&hdma_adc1);
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
}
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
HAL_MspInit();
HAL_ADC_MspInit(&hadc1);
HAL_ADC_Start_DMA(&hadc1, g_ADCBuffer, ADC_BUFFER_LENGTH);
while (1)
{
}
}

#dma #adc #stm32f4
2 REPLIES 2
Posted on November 08, 2015 at 18:12

Observations

8192 is not divisible by THREE, data is likely to precess from iteration to iteration.

ADC+DMA don't stop in the debugger, you'd want to copy out a snap-shot, and view that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
t_shibata
Associate
Posted on November 25, 2015 at 08:45

Hi clive1!

Thank you very much !

Sorry !  I have implemented the different program now.

So, I can't check your advice. I have thought your advice is right