cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 F4 Timer Input capture

SSchu.4
Associate II

Dear community,

I am trying to use a timer to see if there is no activity on a data line. However, it works not as expected.

As you can see in the picture, the timer (yellow) gets interrupts when the signal line (pink) is changing. But no interrupt, when there is no change. I want the opposite.

See my configuration below.

static void MX_TIM2_Init(void)
{
 
  /* USER CODE BEGIN TIM2_Init 0 */
 
  /* USER CODE END TIM2_Init 0 */
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  /* USER CODE BEGIN TIM2_Init 1 */
 
  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 2;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 500;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  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_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  /* USER CODE END TIM2_Init 2 */
 
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
	if (htim->Instance == TIM2) {
		__HAL_TIM_SetCounter(&htim2, 0); //reset counter after input capture interrupt occurs
	}
}

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
	HAL_GPIO_TogglePin(DSP_RST_GPIO_Port, DSP_RST_Pin);
	//HAL_GPIO_WritePin(DSP_RST_GPIO_Port, DSP_RST_Pin, GPIO_PIN_SET);
  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */
 
  /* USER CODE END TIM2_IRQn 1 */
}

2 REPLIES 2

So, you want interrupt also upon timer Update (rollover), correct?

Does the timer run? Observe the TIMx_CNT register in debugger, does it change? And is the Update interrupt enabled in TIMx_DIER?

I don't use Cube/CubeMX and don't understand the Cube/HAL functions.

JW

TDK
Guru

The problem is that the IRQ handler is being called on input capture events, and not on update events, and also that you're not checking to see which event triggered it.

Enable the timer update interrupt:

/* USER CODE BEGIN TIM2_Init 2 */
        __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); // <---
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  /* USER CODE END TIM2_Init 2 */

In the IRQ handler, check the SR bits to see which interrupt (IC or update) is being triggered:

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
   if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET) { // <---
    HAL_GPIO_TogglePin(DSP_RST_GPIO_Port, DSP_RST_Pin);
  }
  /* USER CODE END TIM2_IRQn 0 */
  ...

Code untested, but that's the idea.

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