Skip to main content
CCont.3
Associate
September 10, 2021
Question

Start ADC from timer external input

  • September 10, 2021
  • 1 reply
  • 734 views

Hello,

I'm working on a nucleo-f401re board, with HAL library.

I'm trying sampling a signal and measure its duration, to do it I'm triyng to use the TIM2 of my board to detect rising and falling edges of the start signal, and this works fine.

I would also start the ADC conversion with the same input signal on the same timer input pin if it is possible, but if I start the ADC in DMA mode the interrupts aren't fired.

Please if it is poddible someone could check my code?

MAIN:

int main(void)
{
 HAL_Init();
 
 SystemClock_Config();
 
 MX_DMA_Init();
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 MX_ADC1_Init();
 MX_TIM2_Init();
 
#ifdef DEBUG
 /* freeze TIM2 */
 DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
#endif
 
 /* get timer clock */
 FreqPCLK1 = HAL_RCC_GetPCLK1Freq();
 
 HAL_ADC_Start_DMA(&hadc1, (uint32_t *) ADCbuf, ADCbuf_size);
 HAL_TIM_Base_Start(&htim2);
 
// HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);	//falling edge IC
// HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);	//rising edge IC
 
 while (1)
 {
 /* code */
 }
}
/===================================================================
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) {
	/* falling edge */
	if(HAL_TIM_GetActiveChannel(htim) == HAL_TIM_ACTIVE_CHANNEL_1) {
		 FallingEdge = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
	 }else{ /* rising edge */
		 RisingEdge = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);
		 BurstEndTime_f = 1;
	 }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
	int i = 0;
	i++;
}
/* ADC sampling complete */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
	BurstEndSampling_f = 1;
}

CONFIG:

void MX_ADC1_Init(void)
{
 ADC_ChannelConfTypeDef sConfig = {0};
 
 hadc1.Instance = ADC1;
 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
 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_T2_CC2;	// ADC_EXTERNALTRIGCONV_T2_TRG
 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc1.Init.NbrOfConversion = 1;
 hadc1.Init.DMAContinuousRequests = DISABLE;
 hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
 if (HAL_ADC_Init(&hadc1) != HAL_OK)
 {
 Error_Handler();
 }
 
 sConfig.Channel = ADC_CHANNEL_0;
 sConfig.Rank = 1;
 sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
}
 
void MX_DMA_Init(void)
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA2_CLK_ENABLE();
 
 /* DMA interrupt init */
 /* DMA2_Stream0_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
 
void MX_TIM2_Init(void)
{
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_IC_InitTypeDef sConfigIC = {0};
 
 htim2.Instance = TIM2;
 htim2.Init.Prescaler = 100;
 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim2.Init.Period = 100;
 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
 sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
 sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
 sConfigIC.ICFilter = 0;
 if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
 sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
 if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
}

This topic has been closed for replies.

1 reply

S.Ma
Principal
September 12, 2021

Try to connect externally the timer input channel to the adc normal channel trigger input pin to launch an adc conversion. Once this work, dig in the internal trigger signal. Split your debug.