cancel
Showing results for 
Search instead for 
Did you mean: 

Why would an ADC sample in 8-bit mode when DMA is used, but when used without DMA the full 12-bit conversion is retrieved. - STM32F411

TCloe.1
Associate II

I am trying to set up an example project for ADC with DMA using HAL library.

I am sampling a slow ramp function from 0-3.3V over 2500ms.

For conventional ADC setup:

When debugging the code I can see that the retrieved ADC value the full 12 bits.

For ADC with DMA:

When debugging I see 2 possible issues.

->Firstly, the retrieved ADC value is 8-bit. The value only reaches 255 then overflows and starts at 0 again.

->Secondly, the buffer array does not seem to populate in either normal or circular fashion. Only the first element is populated with this above mentioned 8-bit value.

My ADC and DMA setup is as follows:

static void MX_ADC1_Init(void)

{

 ADC_ChannelConfTypeDef sConfig = {0};

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.ScanConvMode = DISABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DMAContinuousRequests = ENABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 sConfig.Channel = ADC_CHANNEL_0;

 sConfig.Rank = 1;

 sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

}

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA2_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA2_Stream4_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);

 hdma_adc1.Instance = DMA2_Stream4;

 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;

}

14 REPLIES 14

The gist of the code is as follows:

ADC_HandleTypeDef hadc1;

DMA_HandleTypeDef hdma_adc1;

uint16_t adcVal[10];

int main(){

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_ADC1_Init();

MX_DMA_Init();

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcVal, 10);

while(1){ }

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

//

HAL_GPIO_TogglePin(UserLed_GPIO_Port, UserLed_Pin);

HAL_Delay(250);

}

Hello @TCloe.1​ ,

According to this part of your code, I would advise you this update: the MX_DMA_Init() shall be called BEFORE any other peripheral initialization.

This is a limitation with CubeMx v6.3.0 and it will be fixed in the next release.

When your question is answered, please close this topic by choosing Select as Best. This will help other users find that answer faster.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Danish1
Lead II

Looking at your code, I can see that you are setting up the width of data-transfer in hdma_adc1.init inside MX_DMA_Init().

But I don't see anywhere in the code you've shown that tells the HAL to use those values in hdma_adc1 to configure the capture. And without that, who knows what width the transfer will be.

You'd need to do something along the lines of

hadc1.DMA_Handle = &hdma_adc1;

prior to calling HAL_ADC_Start_DMA()

(I should add that I don't use HAL so I haven't learned the correct way to use it)

Hope this helps,

Danish

TDK
Guru

> MX_ADC1_Init();

> MX_DMA_Init();

DMA initialization needs to be before ADC initialization.

Maybe one day ST will fix the bug they introduced in CubeMX regarding initialization order. Until then, we all get to spend time debugging odd behavior on posts like these.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you this was the issue.