Skip to main content
l.kopp
Associate II
May 20, 2019
Question

STM32F303: Injected ADC triggered with TIM1

  • May 20, 2019
  • 2 replies
  • 1290 views

Hello everybody,

i have a motor control application and try to trigger a ADC in injected conversion mode with the Output Compare (OC4REF) trigger of TIM1. With my configuration the ADC convert only once and then never reach the HAL_ADCEx_InjectedConvCpltCallback again.

Here is my Init configuration:

/**
 * @brief ADC2 Initialization Function
 * @param None
 * @retval None
 */
static void MX_ADC2_Init(void)
{
 
 /* USER CODE BEGIN ADC2_Init 0 */
 
 /* USER CODE END ADC2_Init 0 */
 
 ADC_InjectionConfTypeDef sConfigInjected = {0};
 
 /* USER CODE BEGIN ADC2_Init 1 */
 
 /* USER CODE END ADC2_Init 1 */
 /** Common config 
 */
 hadc2.Instance = ADC2;
 hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
 hadc2.Init.Resolution = ADC_RESOLUTION_12B;
 hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE; 
 hadc2.Init.ContinuousConvMode = DISABLE;
 hadc2.Init.DiscontinuousConvMode = DISABLE;
 hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc2.Init.NbrOfConversion = 1;
 hadc2.Init.DMAContinuousRequests = DISABLE;
 hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 hadc2.Init.LowPowerAutoWait = DISABLE;
 hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
 if (HAL_ADC_Init(&hadc2) != HAL_OK)
 {
 Error_Handler();
 }
 /** Configure Injected Channel 
 */
 sConfigInjected.InjectedChannel = ADC_CHANNEL_1;
 sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
 sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
 sConfigInjected.InjectedNbrOfConversion = 1;
 sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_61CYCLES_5;
 sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;
 sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_TRGO;
 sConfigInjected.AutoInjectedConv = DISABLE;
 sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
 sConfigInjected.QueueInjectedContext = ENABLE;
 sConfigInjected.InjectedOffset = 0;
 sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
 if (HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN ADC2_Init 2 */
 
 /* USER CODE END ADC2_Init 2 */
 
}
 
/**
 * @brief TIM1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_TIM1_Init(void)
{
 
 /* USER CODE BEGIN TIM1_Init 0 */
 
 /* USER CODE END TIM1_Init 0 */
 
 TIM_SlaveConfigTypeDef sSlaveConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};
 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
 
 /* USER CODE BEGIN TIM1_Init 1 */
 
 /* USER CODE END TIM1_Init 1 */
 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 1600;
 htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
 htim1.Init.Period = 2250;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 1;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
 sSlaveConfig.InputTrigger = TIM_TS_ITR1;
 if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;
 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 1125;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
 {
 Error_Handler();
 }
 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
 sBreakDeadTimeConfig.DeadTime = 0;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.BreakFilter = 0;
 sBreakDeadTimeConfig.Break2State = TIM_BREAK2_ENABLE;
 sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
 sBreakDeadTimeConfig.Break2Filter = 0;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM1_Init 2 */
 
 /* USER CODE END TIM1_Init 2 */
 
}

In the Callback I read the ADC Value into a Variable:

/**
 * @brief Injected conversion complete callback in non blocking mode 
 * @param hadc ADC handle
 * @retval None
 */
 
int16_t s16DCVoltage = 0;
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
		s16DCVoltage = 1023 * HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1) / 4095;
}

In the main i start the timer and the adc like this:

/* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_ADC2_Init();
 MX_TIM1_Init();
 /* USER CODE BEGIN 2 */
	
	/**
	****************************************************************************
	* ADC Configuration
	****************************************************************************
	*/
	
	// Perform an ADC automatic self-calibration
	if ( HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED) != HAL_OK )
 {
 Error_Handler();
 }
	__HAL_ADC_ENABLE_IT(&hadc2,ADC_IT_JEOC);
 
	// Enables ADC, starts conversion of injected group with interruption
	if ( HAL_ADCEx_InjectedStart_IT(&hadc2) != HAL_OK )
 {
 Error_Handler();
 }
	
	/**
	****************************************************************************
	* TIM1 Configuration
	****************************************************************************
	*/
	
	// Start TIM1 
	if ( HAL_TIM_Base_Start(&htim1) != HAL_OK )
 {
 Error_Handler();
 }
	
	// Start the PWM signal generation in interrupt mode
	if ( HAL_TIM_PWM_Start_IT(&htim1,TIM_CHANNEL_4) != HAL_OK )
 {
 Error_Handler();
 }
 
 
	
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
		u16TimerVal = __HAL_TIM_GET_COUNTER(&htim1);
		
		//Enables ADC, starts conversion of injected group with interruption
		HAL_ADCEx_InjectedStart_IT(&hadc2);
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */

Maybe anyone can help me with my problem =)

Thx

This topic has been closed for replies.

2 replies

Mohamed Aymen HZAMI
ST Employee
October 18, 2019

Hello,

Can you please share with us the wiring of your card.

Best Regards,

Mohamed Aymen.

dbeta.1
Explorer II
January 8, 2021

same problem, but I need to trigger with software