Skip to main content
Explorer
May 2, 2024
Solved

input capture method using stm32f303RBT6 Mcu

  • May 2, 2024
  • 2 replies
  • 2062 views

Hi Team,

We use stm32f303Rbt6 microcontroller. I need a output for Input capture, I am using two timers. I generate pulse for Tim1(1khz) and I set for Tim2 for input capture mode(input capture direct mode). TIM1 generate the pulse for continuously(1khz). But TIM2 set the mode for frequency capture in rising edge only. But we did not get the output and I enable the global interrupt for TIM2. But HAL_TIM_IC_CaptureCallback function does not woring my code. So we did not get the output for Frequency. So I'm already try this method to develop my code. I attach my code and I made a mistake pls correct me.

TIM1 and TIM2 Configuration Pictures.

#include "main.h"Screenshot (24).pngScreenshot (25).png
#include "tim.h"
#include "gpio.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
 
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t IC_Val1 = 0;
uint32_t IC_Val2 = 0;
uint32_t Difference = 0;
int Is_First_Captured = 0;
 
uint16_t i=0,hi=0;
float Ref_clock;
 
uint32_t Frequency=0;
 
 
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)  // Input_Capture Call Back Function
{
if(htim->Instance==TIM3)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)   // if first Value is not captured
{
 
if(Is_First_Captured==0)
{
IC_Val1 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);  // captured the first value
Is_First_Captured=1;    // set the value is captured now
}
else 
{
IC_Val2 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);  // captured the second value
if(IC_Val2 > IC_Val1)    // if the second value is higher
{
Difference = IC_Val2 - IC_Val1;
}
else if(IC_Val2 > IC_Val1)
{
Difference = ((0xffff - IC_Val1) + IC_Val2) +1;
}
 
// frequency = tim2_clk/Difference
 
Ref_clock = 36000000/719;
Frequency = Ref_clock/ Difference;
__HAL_TIM_SET_COUNTER(htim, 0);     // reset the counter
Is_First_Captured=0;
}
 
}
 
}
 
}
 
 
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
 
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);        // PWM_GENERATE_TIM1_15KHZ
 
  HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);      // INPUT_CAPTURE_PWM_IT_START
 
  HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);
// HAL_TIM_Base_Start_IT(&htim3);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
 
//   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, 1);
//HAL_Delay(10);
//   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, 0);
HAL_Delay(1000);
 
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
    This topic has been closed for replies.
    Best answer by Sarra.S

    Hello @mrsmile

    1) There is an incorrect logical comparison in your code, both conditions are the same: 

    if(IC_Val2 > IC_Val1) // if the second value is higher
    {
    Difference = IC_Val2 - IC_Val1;
    }
    else if(IC_Val2 > IC_Val1)
    {
    Difference = ((0xffff - IC_Val1) + IC_Val2) +1;
    }

     The second condition should be if(IC_Val1 > IC_Val2) to handle the timer overflow correctly.

    2) Also, your Ref_clock calculation seems arbitrary? 

    3) You are resetting the counter of htim in the callback wrongly here:   

    __HAL_TIM_SET_COUNTER(htim, 0); // reset the counter

    you should specify the timer instance explicitly, like __HAL_TIM_SET_COUNTER(&htim3, 0);

    4) You start the PWM with HAL_TIM_PWM_Start and then again with HAL_TIM_PWM_Start_IT for the same channel here

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // PWM_GENERATE_TIM1_15KHZ
     
     HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); // INPUT_CAPTURE_PWM_IT_START
     
     HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);

    You should only start it once! 

    5) The variables i and hi are declared but not used in your code.

    6) Make sure that the global interrupt for TIM2 is enabled in NVIC, and verify they are correctly configured in terms of prescaler, clock source,..

    2 replies

    Sarra.SAnswer
    ST Employee
    May 2, 2024

    Hello @mrsmile

    1) There is an incorrect logical comparison in your code, both conditions are the same: 

    if(IC_Val2 > IC_Val1) // if the second value is higher
    {
    Difference = IC_Val2 - IC_Val1;
    }
    else if(IC_Val2 > IC_Val1)
    {
    Difference = ((0xffff - IC_Val1) + IC_Val2) +1;
    }

     The second condition should be if(IC_Val1 > IC_Val2) to handle the timer overflow correctly.

    2) Also, your Ref_clock calculation seems arbitrary? 

    3) You are resetting the counter of htim in the callback wrongly here:   

    __HAL_TIM_SET_COUNTER(htim, 0); // reset the counter

    you should specify the timer instance explicitly, like __HAL_TIM_SET_COUNTER(&htim3, 0);

    4) You start the PWM with HAL_TIM_PWM_Start and then again with HAL_TIM_PWM_Start_IT for the same channel here

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // PWM_GENERATE_TIM1_15KHZ
     
     HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); // INPUT_CAPTURE_PWM_IT_START
     
     HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);

    You should only start it once! 

    5) The variables i and hi are declared but not used in your code.

    6) Make sure that the global interrupt for TIM2 is enabled in NVIC, and verify they are correctly configured in terms of prescaler, clock source,..

    mrsmileAuthor
    Explorer
    May 3, 2024

    1) I correct the logical comparison in my code and attached the Image.

    2) My reference clock calculation not arbitary. reference clock TIM3 and APB1 36 MHZ.

    I generate the frequency in tim3 for PSC-719, ARR-65535, clk - 72000000, frequency- 1.5 hz.

    3) Yes, are resetting the counter of htim in the callback. Correct my mistake and change my code.

      __HAL_TIM_SET_COUNTER(&htim3, 0); // reset the counter

    4) Yes, start the PWM with HAL_TIM_PWM_Start and generate the pulse in TIM1_CH1.But I did not use the interrupt handler HAL_TIM_PWM_Start_IT. I am using only this HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2) call back fucntion only.

     5) sure that the global interrupt for TIM3 is enabled in NVIC.

    it's my code was working but counter values did'nt get the rising edge.call back function also called but output did not come. so am stuck this stage. so what can I do for next step.

    If your any possible way to provide sample code for inpu capture STM32f303RBt6 this Microcontroller.

    I attach my code Once again.

     

    #include "main.h"
    #include "tim.h"
    #include "gpio.h"
     
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
     
    /* USER CODE END Includes */
     
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
     
    /* USER CODE END PTD */
     
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
     
    /* USER CODE END PD */
     
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
     
    /* USER CODE END PM */
     
    /* Private variables ---------------------------------------------------------*/
     
    /* USER CODE BEGIN PV */
    uint32_t counter_0=0,counter_1=0;
    uint32_t counter=0;
    uint8_t gap=0;
    uint16_t Frequency=0;
     
    uint32_t IC_Val1 = 0;
    uint32_t IC_Val2 = 0;
    uint32_t Difference = 0;
    int Is_First_Captured = 0;
     
     
     
     
    /* USER CODE END PV */
     
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
     
    /* USER CODE END PFP */
     
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
     
    /* USER CODE END 0 */
     
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
     
      /* USER CODE BEGIN 1 */
     
      /* USER CODE END 1 */
     
      /* MCU Configuration--------------------------------------------------------*/
     
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
     
      /* USER CODE BEGIN Init */
     
      /* USER CODE END Init */
     
      /* Configure the system clock */
      SystemClock_Config();
     
      /* USER CODE BEGIN SysInit */
     
      /* USER CODE END SysInit */
     
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_TIM1_Init();
      MX_TIM3_Init();
      /* USER CODE BEGIN 2 */
     
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);        // PWM_GENERATE_TIM1_15KHZ
     
      HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);      // INPUT_CAPTURE_PWM_IT_START
     
      HAL_TIM_Base_Start_IT(&htim3);
      /* USER CODE END 2 */
     
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
     
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)  // Input_Capture Call Back Function
    {
    if(htim->Instance==TIM3)
    {
    if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)   // if first Value is not captured
    {
     
    if(Is_First_Captured==0)
    {
    IC_Val1 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);  // captured the first value
    Is_First_Captured=1;    // set the value is captured now
    }
    else 
    {
    IC_Val2 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);  // captured the second value
    if(IC_Val2 > IC_Val1)    // if the second value is higher
    {
    Difference = IC_Val2 - IC_Val1;
    Frequency = 100000/ Difference;
    }
    else 
    {
    Difference = ((IC_Val2 + 0xffff ) - IC_Val1) +1;
      Frequency = 100000/ Difference;
    }
     
    // frequency = tim2_clk/Difference
    IC_Val2 = IC_Val1;
    __HAL_TIM_SET_COUNTER(&htim3, 0);     // reset the counter
     
    Is_First_Captured=0;
    }
     
    }
     
    }
     
    }

    Screenshot 2024-05-03 120752.png

    ST Employee
    May 3, 2024

    Hello again @mrsmile

    Please check this InputCapture example project in STM32F3CubeFW 

    mrsmileAuthor
    Explorer
    May 3, 2024

    this is not working. Can you share any other example programme references for stm32f303rbt6.