Skip to main content
l.kopp
Associate II
May 20, 2019 8:54 AM UTC
Question

STM32F303: Injected ADC triggered with TIM1

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
Oct 18, 2019 7:48 AM UTC

Hello,

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

Best Regards,

Mohamed Aymen.

dbeta.1
Explorer II
Jan 8, 2021 4:45 AM UTC

same problem, but I need to trigger with software