Skip to main content
vmb.sd1
Associate
January 21, 2022
Solved

STM32L152RE (Nucleo64) ADC DMA (HAL) problems

  • January 21, 2022
  • 5 replies
  • 2298 views

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();

}

This topic has been closed for replies.
Best answer by Imen.D

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

5 replies

Imen.DBest answer
ST Technical Moderator
January 21, 2022

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

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
vmb.sd1
vmb.sd1Author
Associate
January 21, 2022

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

ST Technical Moderator
January 21, 2022

Glad to know the issue has been solved :)

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

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
vmb.sd1
vmb.sd1Author
Associate
January 21, 2022

:thumbs_up: