cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Triggering with TIM3 TRGO running in PWM mode

KVeer.1
Associate II

Hello all and good day!

I have been trying to trigger an ADC using TIM6 with TRGO signal in STM32F446RE board. I am unable to do it. I have used CubeMX initialization and have been trying to use the HAL libraries for developing the code. I have attached screenshots of how my settings in CubeMX environment look and am very unsure where I am making a mistake.

I have used the following code to acquire the results in the ADC

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  //UNUSED(hadc);
	if(hadc->Instance == ADC1)
	{
		adc1 = HAL_ADC_GetValue(&hadc1);
		HAL_GPIO_TogglePin(GPIOB, LED1_Pin); //test LED
	}
 
}

The timer initialization generated by Cube MX looks as follows

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{
 
  /* USER CODE BEGIN TIM3_Init 0 */
 
  /* USER CODE END TIM3_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
 
  /* USER CODE BEGIN TIM3_Init 1 */
 
  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 180;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 90;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
 
  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);
 
}

The ADC initialization looks as follows:

/**
  * @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_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  if (HAL_ADC_Init(&hadc1) != 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_0;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}

and lastly, I am starting the timer with the following commnad:

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

I am not using the interrrupt version (HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); as the Timer is not running in interrupt mode. Its just providing the SOC trigger pulse.

I have also been advised earlier to write my on code (something that I always am accustomed to doing) but have been trying out the new environment. I'd greatly appreciate any help regarding this issue.

Thank you very much in advance 🙂

Stay safe y'all!

2 REPLIES 2
TDK
Guru

Not sure it’s the root of the problem, but your timer updates every 181 timer clock cycles, and you’re calling an interrupt at that frequency. It’s unlikely your interrupt will execute fast enough. Slow the timer down, or use DMA.

If you feel a post has answered your question, please click "Accept as Solution".

@TDK thank you for your reply!

So, I took your suggestion and tried slowing down my timer from 500KHz to 10KHz. However, the ADC would'nt fire even in that situation. This means my peripheral initialization is incorrect. Not really sure how to go about doing it.