Skip to main content
RN_it
Associate III
May 19, 2018
Question

STM32F4 Timer Input capture problem

  • May 19, 2018
  • 10 replies
  • 2181 views
Posted on May 19, 2018 at 12:48

Hello , 

I am using stm32f446re nucleo board . and i face some issue in timer input capture . 

here i am using 2 timers TIM6 ( for time base generation ) and TIM2 (free running input capture purpose)

actually my code is working fine when i run the first timer(TIM6) at 10 micro or 100 micro second time base generation . I actually toggle the gpio in IRQ handler of TIM6 and that is input to the TIM2 input channel where i detect the gap between rising and falling edge of a gpio . TIM2 actually DMA the content of CCR1 to memory . 

as i said this works  fine when i use the TIM6 for 10 micro and 100 micro time base generation 

but when i use the TIM6 for 1 mirco second time base generation , the TIM2 is not giving correct values for the gpio toggling . Can you please help me to understand what is going wrong ?

i am using AHB = 84Mhz, timer clock = 48Mhz. 

Here is a code 

int main(void)

{

/* USER CODE BEGIN 1 */

uint32_t diffCapture=0;

double frequency=0;

char msg[30];

/* 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_DMA_Init();

MX_USART2_UART_Init();

MX_TIM6_Init();

MX_TIM2_Init();

/* USER CODE BEGIN 2 */

HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t*) captures, 2);

HAL_TIM_Base_Start_IT(&htim6);

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

   if (captureDone != 0) {

   if (captures[1] >= captures[0])

   diffCapture = captures[1] - captures[0];

   else

   diffCapture = (htim2.Instance->ARR - captures[0]) + captures[1];

   frequency = HAL_RCC_GetPCLK1Freq() / (htim2.Instance->PSC + 1);

   frequency = (float) frequency / diffCapture;

   sprintf(msg, 'Input frequency: %.3f\r\n', frequency);

   //HAL_UART_Transmit(&huart2, (uint8_t*) msg, strlen(msg), HAL_MAX_DELAY);

   //while (1);

}

}

}

/* TIM2 init function */

static void MX_TIM2_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig;

TIM_IC_InitTypeDef sConfigIC;

htim2.Instance = TIM2;

htim2.Init.Prescaler = 0;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = 65535;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_IC_Init(&htim2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

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_1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

/* TIM6 init function */

static void MX_TIM6_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig;

htim6.Instance = TIM6;

htim6.Init.Prescaler = 0;

htim6.Init.CounterMode = TIM_COUNTERMODE_UP;

htim6.Init.Period = 47;

if (HAL_TIM_Base_Init(&htim6) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

/* USER CODE BEGIN 4 */

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {

if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {

captureDone = 1;

}

}
    This topic has been closed for replies.

    10 replies

    waclawek.jan
    Super User
    May 19, 2018
    Posted on May 19, 2018 at 13:28

    actually toggle the gpio in IRQ handler of TIM6

    when i use the TIM6 for 1 mirco second time base generation , the TIM2 is not giving correct values for the gpio toggling

    Executing the IRQ handler probably takes more than 1 microsecond.

    Observe the waveform with an oscilloscope or logic analyzer. Better yet, use a timer with output channel and generate the waveform purely in hardware (PWM).

    JW

    RN_it
    RN_itAuthor
    Associate III
    May 19, 2018
    Posted on May 19, 2018 at 13:42

    Thanks for the reply , 

    Actually TIM2 runs till 65535( @48Mhz) that is  ~1.3ms , even if TIM6 IRQ handler takes more than 1mirco second , it shouldnt be problem for input compare isnt it ?

    waclawek.jan
    Super User
    May 19, 2018
    Posted on May 19, 2018 at 17:47

    Problem is not with the input capture of TIM2, but with the signal generation using interrupt of TIM6.

    JW

    Tesla DeLorean
    Guru
    May 19, 2018
    Posted on May 19, 2018 at 17:19

    TIM2 should be 32-bit, you should use full range (0xFFFFFFFF)

     diffCapture = captures[1] - captures[0]; // should work with ALL values, wrapping will be managed/contained within the uint32_t math

    The TIM Clock on APB1 (PCLK1) will typically be PCLK*2 for any divider other than 1

    >>i am using AHB = 84Mhz, timer clock = 48Mhz. 

    Half of 84 is 42, not 48, the TIMCLK in this context will almost certainly be 84 MHz

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    RN_it
    RN_itAuthor
    Associate III
    May 20, 2018
    Posted on May 20, 2018 at 08:26

    Thanks . i am sorry,  the config is AHB=84Mhz and timer clock = 84Mhz as you said. can i get 1Mhz of output toggling using timer 2 ? is there any register where i can configure the pulse value and it generates output waveform auto feeding the output compare register ? instead of feeding it through DMA or IRQ handler ?

    waclawek.jan
    Super User
    May 20, 2018
    Posted on May 20, 2018 at 23:30

    Autonomously outputting pulses - this is what the PWM mode of timer is all about.

    So, read about PWM.

    JW

    henry.dick
    Associate II
    May 19, 2018
    Posted on May 19, 2018 at 17:27

    '

    when i use the TIM6 for 1 mirco second time base generation ,'

    make sure the ISR can be executed within that time framework.

    Tesla DeLorean
    Guru
    May 19, 2018
    Posted on May 19, 2018 at 17:31

    The 8-ball here says ''signs point to no''

    0690X0000060KrgQAE.png
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    bonmotwang
    Associate
    October 8, 2018

    A off topic question here.

    I am doing a simulator task right now. I found that I cannot use STM32CUBE to generate HAL_TIM_IC_CaptureCallback for TIM15. I am using 32F030.

    Did I miss anything?