cancel
Showing results for 
Search instead for 
Did you mean: 

Correct Timer Configuration for Capturing Edge Times In Order to Calculate Pulse Width

EGold.3
Associate II

Hi, I am using an STM32F429 to calculate the pulse times from an an IR receiver. The IR receiver outputs a signal that follows the NEC Protocol, which is defined here: https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol

The protocol defines a maximum pulse length of 9ms and a minimum pulse length of 500 microseconds, and a frequency of 38kHz

I have configured Timer2 to generate timer capture interrupts on both rising and falling edges. Here is my initialization process:

void McuInit_TIM2(void)
{
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period =  9999;
  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_BOTHEDGE;
  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();
  }
  
  HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
 
}

With this configuration I see behavior in which my interrupt fires not on every rising or falling edge. I am seeing, per transmission of one full NEC protocol message, 8-10 edges only recorded of the 60+ present in every NEC message.

I believe my confusion lies in the relationship between frequency and period the Timer being used as an input capture. The clock source for TIM2 is 72MHz, and TIM2 has no prescaler and a period of 10,000. My understanding is that this means the timer counter will roll over every:

(10,000/72,000,000) seconds, or ~.1 milliseconds. However, I also understand that TIM2 is currently configured to run only at a clock frequency of 7.2kHz, slower than the frequency of the IR receiver feeding it signals. I have verified that my ISR is not running for excessively long (I am not using the HAL_IRQ_Handler() and merely place Timer2's CCR value in a buffer when the interrupt fires).

Is my Timer configuration incorrect for attempting to capture edge times of the described signal which runs at 38kHz?

0 REPLIES 0