cancel
Showing results for 
Search instead for 
Did you mean: 

ADC timing issues when configured for multiple channel scanning.

JimEno
Associate II

I'm trying to scan 6 channels at a 1 KHz rate. I used Timer 2 to generate 1 mSec trigger pulses for the ADC. I used the 'interrupt mode' to verify timing by pulsing an I/O port pin. I'll use DMA eventually. I setup the ISR to collect 24 samples and stop. I get 24 evenly spaced pulses (ADC conversions) at 1 mS intervals. I expected to get 4 bursts of 6 pulses (representing the 6-channel scan) with the burst spacing of 1 mS.

The Reference Manual says ALL 6 conversions should occur when triggered (I assume back to back), then the next 6 conversions would be made after the next Timer2 trigger pulse 1 mS later as follows:

|||||| |||||| |||||| ||||||

| 1 mS | 1 mS | 1 mS | = 1 KHz trigger rate

I included the Ref Manual statement below as well as my simple ISR routine. I thought the Timer 2 pulse was a 'sequence' trigger, not a 'conversion' trigger.

Where is my thinking wrong?

Reference Manual snippet:

18.4.13 Single conversion mode (CONT=0)

In Single conversion mode, the ADC performs once all the conversions of the channels. This mode is started with the CONT bit at 0 by either:

• Setting the ADSTART bit in the ADC_CR register (for a regular channel)

• Setting the JADSTART bit in the ADC_CR register (for an injected channel)

• External hardware trigger event (for a regular or injected channel) 

ADC ISR routine:

void ADC_SampleHandler(ADC_HandleTypeDef *hadc)

{

ADCResult = HAL_ADC_GetValue(hadc);

HAL_GPIO_WritePin(CS3_GPIO_Port, CS3_Pin, GPIO_PIN_SET);

for(k=0; k<500; k++);

HAL_GPIO_WritePin(CS3_GPIO_Port, CS3_Pin, GPIO_PIN_RESET);

if(++i == 24)

{

HAL_ADC_Stop_IT(&hadc1);

ADCdoneFlag = TRUE;

}

}

3 REPLIES 3
FBL
ST Employee

Hello @JimEno​,

Would you please specify the STM32 product you are using?

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.

JimEno
Associate II

I am using a Nucleo-L4A6ZG Evaluation Board and a custom daughter board (with an Arduino type interface). We will eventually port the code over to a fully custom board to support our final product.

JimEno
Associate II

Also would like to add that I used the MX Code Generation tool to configure the ADC resource. It's a little lengthy, but here is the result:

/**

 * @brief ADC1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_ADC1_Init(void)

{

 /* USER CODE BEGIN ADC1_Init 0 */

 /* USER CODE END ADC1_Init 0 */

 ADC_MultiModeTypeDef multimode = {0};

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */

 /* USER CODE END ADC1_Init 1 */

 /** Common config

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc1.Init.LowPowerAutoWait = DISABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.NbrOfConversion = 6;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

 hadc1.Init.DMAContinuousRequests = DISABLE;

 hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;

 hadc1.Init.OversamplingMode = DISABLE;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure the ADC multi-mode

 */

 multimode.Mode = ADC_MODE_INDEPENDENT;

 if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_4;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;

 sConfig.SingleDiff = ADC_SINGLE_ENDED;

 sConfig.OffsetNumber = ADC_OFFSET_NONE;

 sConfig.Offset = 0;

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

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_1;

 sConfig.Rank = ADC_REGULAR_RANK_2;

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

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_2;

 sConfig.Rank = ADC_REGULAR_RANK_3;

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

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_8;

 sConfig.Rank = ADC_REGULAR_RANK_4;

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

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_13;

 sConfig.Rank = ADC_REGULAR_RANK_5;

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

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_14;

 sConfig.Rank = ADC_REGULAR_RANK_6;

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

 {

  Error_Handler();

 }

 /* USER CODE BEGIN ADC1_Init 2 */

 if (HAL_ADC_RegisterCallback(&hadc1, HAL_ADC_CONVERSION_COMPLETE_CB_ID, ADC_SampleHandler) != HAL_OK)

// if (HAL_ADC_RegisterCallback(&hadc1, HAL_ADC_CONVERSION_COMPLETE_CB_ID, ADC_FrameHandler) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE END ADC1_Init 2 */

}