cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F0 ADC DMA Assistance

Eric Placzek
Associate
Posted on April 14, 2017 at 21:19

Hello All,

Hoping someone can help me understand the ADC DMA via ST's HAL. I haven't been able to locate the information I need to understand how it works or what I have read still doesn't give me what I need so if someone refers me to the proper doc I'll take a RTFM response if it clearly gives me the understanding I am looking for.

Essentially I have 4 ADC's (in 12 bit resolution mode) and I am trying capture that data and convert it (ie temp, moisture, ect..). Trying to understand how the API works for the DMA conversion and how my 4 ADC channels align in my assigned pointer. Below outlines what I currently have set up, and highlighted in red text is where my confusion is.

I am using the STM32F072RB custom board design, used CubeMX to set up the ADC:

Below is called in my main function:

if (HAL_ADC_Start_DMA(&hadc, (uint32_t*)ADC1ConvertedValues,

1024

) != HAL_OK)

  return 0;

Below is in my while loop:

sprintf((char *)str, ''ADC Val: %d %d %d %d\r\n'', ADC1ConvertedValues[

0

], ADC1ConvertedValues[

1

], ADC1ConvertedValues[

2

], ADC1ConvertedValues[

3

]); // Want my 4 ADC channels to print the individual ADC value read.

  len = strlen((char *)str);

  HAL_UART_Transmit(&huart2, str, len, 1000);

Debugger Watch result:

0690X00000606moQAA.png

/* ADC init function */

static void MX_ADC_Init(void)

{

  ADC_ChannelConfTypeDef sConfig;

    /**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_DIRECTION_FORWARD;

  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

  hadc.Init.LowPowerAutoWait = DISABLE;

  hadc.Init.LowPowerAutoPowerOff = DISABLE;

  hadc.Init.ContinuousConvMode = ENABLE;

  hadc.Init.DiscontinuousConvMode = DISABLE;

  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  hadc.Init.DMAContinuousRequests = ENABLE;

  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

  if (HAL_ADC_Init(&hadc) != HAL_OK)

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_4;

  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

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

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_10;

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

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_11;

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

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_12;

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

  {

    Error_Handler();

  }

}

#adc
1 REPLY 1
Jinhui Lin
Associate II
Posted on April 15, 2017 at 15:30

if (HAL_ADC_Start_DMA(&hadc, (uint32_t*)ADC1ConvertedValues,

1024

) != HAL_OK); 

1024 is not correct, it should be 4 for you, I think.

STM32F7xx HAL Library Descriped as below:

/**

* @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral

* @param hadc: pointer to a ADC_HandleTypeDef structure that contains

* the configuration information for the specified ADC.

* @param pData: The destination Buffer address.

* @param Length:

The length of data to be transferred from ADC peripheral to memory.

* @retval HAL status

*/

HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);

Read 4-ADC-Channel to memnory

static uint16_t adc_buffer[4];

// 

hadc1.Init.NbrOfConversion == 4

if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buffer, hadc1.Init.NbrOfConversion) != HAL_OK);

HAL_Delay(500);

HAL_ADC_Stop_DMA(&hadc1);

and add what you want in completed callback function:

/**

* @brief Conversion complete callback in non blocking mode

* @param AdcHandle : AdcHandle handle

* @note This example shows a simple way to report end of conversion, and

* you can add your own implementation.

* @retval None

*/

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)

{

// TODO

__NOP();

}