cancel
Showing results for 
Search instead for 
Did you mean: 

What is Best Way to configure ADC when you have multiple channels on STM32f042F6px

pradeepwagre
Associate III

Hello I am beginner on STM32,previously once I configured only one ADC channel and I was using interrupt mode for it so I new ADC interrupt which is getting generated is coming because of only a single channel after its conversion.At that time I used "End of single conversion". Now I want to understand what happens when we configure multiple ADC channels does the interrupt comes whenever any channel completes the conversion or interrupt is generated when all channel completes the conversion?what happens if I use "END of Sequence of conversion"?What is the difference between End of single conversion and End of sequence conversion?

4 REPLIES 4
Stassen.C
ST Employee

Hello Pradeepwagre,

Please find here the getting started wiki for the ADC. It should answer your question and give you an example as well.

Regards,
Stassen

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

static void MX_ADC_Init(void)
{

/* USER CODE BEGIN ADC_Init 0 */

/* USER CODE END ADC_Init 0 */

ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC_Init 1 */

/* USER CODE END ADC_Init 1 */

/** 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_SEQ_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
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_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_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_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */

HAL_ADCEx_Calibration_Start(&hadc);
HAL_ADC_Start_IT(&hadc);
/* USER CODE END ADC_Init 2 */

}

Above code is my ADC initialization,I have configured 4 ADC channels here.I can see ADC interrupt is getting triggered.

void ADC1_IRQHandler(void)
{
/* USER CODE BEGIN ADC1_IRQn 0 */

/* USER CODE END ADC1_IRQn 0 */
HAL_ADC_IRQHandler(&hadc);
/* USER CODE BEGIN ADC1_IRQn 1 */
new_adc = HAL_ADC_GetValue(&hadc);
/* USER CODE END ADC1_IRQn 1 */
}

Above code is my ADC isr,I can ready adc values into new_adc  variable with HAL_ADC_GetValue(&hadc) function.But how I am suppose to know that adc values which I am getting is because of which channel?

 

Simple in IRQ do four gets instead one. ADC uses FIFO

2 choices:

1. After each conversion, reconfigure the ADC for the next channel.

2. Set number of conversions to 4 and use DMA to transfer the conversions to a 4 word buffer, look for end of sequence conversion.

The Examples with the HAL library should provide a DMA example. You may have to edit it to do 4 channels instead of 1.