cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152RE (Nucleo64) ADC DMA (HAL) problems

vmb.sd1
Associate II

Good day!

I'm trying to run ADC DMA mode on the NUCLEO-L152RE board using HAL, but it doesn't work properly. For testing, 3 channels are used: ADC_CHANNEL_6 (RANK 1), ADC_CHANNEL_VREFINT (RANK 2), ADC_CHANNEL_TEMPSENSOR (RANK 3). 2 problems were found out: 1) When channels are sequentially polled, all values ​​are written to one (first) element of the array. 2) The values ​​of all channels are 8 bits, although the ADC resolution is 12bit and a 12 bit value is displayed in the ADC data register. The same code works fine on STM32F103RBT6. Maybe someone knows if there are any BUGs or some peculiarities in using STM32L1 HAL for ADC DMA mode?

Test code:

#include "main.h"

volatile uint16_t ADC_RES[3];

volatile float U_ADC_RES[3];

#define Vref 3.3

//#define TS_CAL1_25 1.34// raw ADC 670

//#define Avg_Slope 0.0043

ADC_HandleTypeDef hadc;

DMA_HandleTypeDef hdma_adc;

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_ADC_Init(void);

static void MX_DMA_Init(void);

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_ADC_Init();

 MX_DMA_Init();

 while (1)

 {

   HAL_ADC_Start_DMA(&hadc,(uint32_t*)&ADC_RES, 3);

// HAL_ADC_Stop_DMA(&hadc1);

     HAL_Delay(200);

     U_ADC_RES[0]=Vref*ADC_RES[0]/4095;

    U_ADC_RES[1]=Vref*ADC_RES[1]/4095;

    U_ADC_RES[2]=Vref*ADC_RES[2]/4095;

    }

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

 RCC_OscInitStruct.HSEState = RCC_HSE_ON;

 RCC_OscInitStruct.HSIState = RCC_HSI_ON;

 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;

 RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

 {

  Error_Handler();

 }

}

static void MX_ADC_Init(void)

{

 ADC_ChannelConfTypeDef sConfig = {0};

 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

 */

 hadc.Instance = ADC1;

 hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

 hadc.Init.Resolution = ADC_RESOLUTION_12B;

 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;

 hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;// hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;

 hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;

 hadc.Init.ContinuousConvMode = ENABLE;

 hadc.Init.NbrOfConversion = 3;

 hadc.Init.DiscontinuousConvMode = DISABLE;

 hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc.Init.DMAContinuousRequests = ENABLE;

 if (HAL_ADC_Init(&hadc) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

 */

 sConfig.Channel = ADC_CHANNEL_6;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES;

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

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

 */

 sConfig.Channel = ADC_CHANNEL_VREFINT;

 sConfig.Rank = ADC_REGULAR_RANK_2;

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

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

 */

 sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;

 sConfig.Rank = ADC_REGULAR_RANK_3;

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

 {

  Error_Handler();

 }

}

}

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Channel1_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}

static void MX_GPIO_Init(void)

{

 /* GPIO Ports Clock Enable */

 __HAL_RCC_GPIOH_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();

 __HAL_RCC_GPIOB_CLK_ENABLE();

}

1 ACCEPTED SOLUTION

Accepted Solutions
Imen.D
ST Employee

Hello @vmb.sd1​ and welcome to the Community 🙂

There is a known CubeMx issue, which generates the DMA_Init function in the wrong order.

Please have a look at this post to fix this issue:

MX_DMA_Init order in the main.c file generated by STM32CubeMX, How to fix?

Hope my answer helped you!

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

View solution in original post

5 REPLIES 5
Imen.D
ST Employee

Hello @vmb.sd1​ and welcome to the Community 🙂

There is a known CubeMx issue, which generates the DMA_Init function in the wrong order.

Please have a look at this post to fix this issue:

MX_DMA_Init order in the main.c file generated by STM32CubeMX, How to fix?

Hope my answer helped you!

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
vmb.sd1
Associate II

👍

Imen, thanks a lot for the instant help!

Everything is working! I spent 2 days fighting this problem, then I decided to write- help came within 5 minutes🙂

Best regards,

Valery

Glad to know the issue has been solved 🙂

Please allow me to close this thread and thank you for your contribution.

Imen

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

Of course, the problem is solved and the issue is closed!

Valery