cancel
Showing results for 
Search instead for 
Did you mean: 

Input Capture Interrupt Problem

Nimit Vachhani
Associate III

Greetings Everybody,

I am using STM32F429I-DISC1 BOARD version MB1075 C-01. My main aim

  1. Generate square wave from 1HZ to 20KHZ - This is completed. I am using Timer5 to generate square wave as per my requirement. I have even checked it on oscillo scope and its working fine.
  2. Detect the frequency of input square wave using Timer2 input capture interrupt. This is not working. I am generating square wave on TIMER5 CHANNEL 1 and giving this as input to TIMER2 CHANNEL 2.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
#include <stdbool.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim5;
 
bool     _pwm_reset      = 0;
uint32_t _pwm_freq 			 = 50;			//	REQUIRED OUTPUT FREQUENCY
uint32_t _pwm_timer_freq = 90000000; //	INPUT FREQUENCY FOR PWM MODULE
uint32_t _arr 		 			 = 0;	//	AUTO RELOAD VALUE FOR PWM FREQ IN _pwm_freq VARIABLE
uint32_t _ccr      			 = 0;				//	DUTY CYCLE VALUE. ALWAYS 50%
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM5_Init(void);
 
/* Private user code ---------------------------------------------------------*/
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM5_Init();
  /* USER CODE BEGIN 2 */
	_arr = _pwm_timer_freq / _pwm_freq;	
	TIM5->ARR  = _arr;
	TIM5->CCR1 = _arr / 2;
	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
  /* USER CODE END 2 */
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		HAL_Delay(1000);
//		if(_pwm_reset)
//		{
//			_arr = _pwm_timer_freq / _pwm_freq;	
//			TIM5->ARR  = _arr;
//			TIM5->CCR1 = _arr / 2;
//			_pwm_reset = 0;
//		}
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
#define TIMCLOCK   90000000
#define PRESCALAR  90
 
uint32_t IC_Val1 = 0;
uint32_t IC_Val2 = 0;
uint32_t Difference = 0;
int Is_First_Captured = 0;
float frequency = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)  // if the interrupt source is channel1
	{
		if (Is_First_Captured==0) // if the first value is not captured
		{
			IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); // read the first value
			Is_First_Captured = 1;  // set the first captured as true
		}
 
		else   // if the first is already captured
		{
			IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);  // read second value
 
			if (IC_Val2 > IC_Val1)
			{
				Difference = IC_Val2-IC_Val1;
			}
 
			else if (IC_Val1 > IC_Val2)
			{
				Difference = (0xffffffff - IC_Val1) + IC_Val2;
			}
 
			float refClock = TIMCLOCK/(PRESCALAR);
 
			frequency = refClock/Difference;
 
			__HAL_TIM_SET_COUNTER(htim, 0);  // reset the counter
			Is_First_Captured = 0; // set it back to false
		}
	}
}
/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{
 
  /* USER CODE BEGIN TIM2_Init 0 */
 
  /* USER CODE END TIM2_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {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 = 90-1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 4294967295;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  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_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */
 
  /* USER CODE END TIM2_Init 2 */
 
}
 
/**
  * @brief TIM5 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM5_Init(void)
{
 
  /* USER CODE BEGIN TIM5_Init 0 */
 
  /* USER CODE END TIM5_Init 0 */
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
 
  /* USER CODE BEGIN TIM5_Init 1 */
 
  /* USER CODE END TIM5_Init 1 */
  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 0;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 1;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_PWM_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 1;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM5_Init 2 */
 
  /* USER CODE END TIM5_Init 2 */
  HAL_TIM_MspPostInit(&htim5);
 
}

Above is my code. I am not able to generate input capture interrupt. In the interrupt i am calculating frequency of input square wave.

Note : Input capture code snippet is taken from some body's online post and sample working project too.

2 REPLIES 2
Javier1
Principal

Hi, i developed your same thing some time ago.

I followed this video (DMA)

and it worked well for me, i can read up to Mhz.

I didnt looked at your code, sorry

we dont need to firmware by ourselves, lets talk
Nimit Vachhani
Associate III

I did follow this video but use. I have another board tooo i will try on that one too. Its nucleo-144 207zg.