cancel
Showing results for 
Search instead for 
Did you mean: 

multi ADC by IT

giwonKIM
Associate II

Hi

 

I'm using 2ch in ADC1 of STM32H735VGT.

I set PIN15 to timer 5 and the waveform appears weird.

 

What's the problem?

 

My ADC1_Init :

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.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.NbrOfDiscConversion = 2;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.OversamplingMode = ENABLE;
hadc1.Init.Oversampling.Ratio = 10;
hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_NONE;
hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
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_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}

My timer Interrup :

 

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if((htim->Instance == TIM5) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1))
{
HAL_ADC_Start_IT(&hadc1);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, SET);
}
}

 

My ADC Interrupt :

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance == ADC1) {
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, RESET);
internal_adc_value[0] = HAL_ADC_GetValue(&hadc1);
internal_adc_value[1] = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop_IT(&hadc1);
func();
}
}

 

thank you.

1 REPLY 1
GwenoleB
ST Employee

Hello @giwonKIM ,

I understand from your code you convert 2 channels on ADC1. In addition, it seems you try to start ADC conversion based on TIM5 PWM mode.

Your PIN15 is set to high between the end of the PWM period of TIM5 and the end of ADC conversion. However, it seems you would like to output the TIM5 PWM on PIN15. It could be easily done by configuring in CubeMX, CH1 PWM output generation or output compare.

In addition, you can also trigger the ADC directly by a timer instead of going through an interrupt.

Finally, in the ADC ISR handler, you are reading two values linked to the channels you have configured. Unfortunately, ADC has only one register DR that can retain one value at a time. Two options are available:

  • Convert the first channel, wait for IT, clear EOC flag, read ADC->DR then wait for the second conversion
  • Use DMA 

Please, let me know if you need any clarification.

Best regards,

Gwénolé