cancel
Showing results for 
Search instead for 
Did you mean: 

How to use Two Channel of TIM2 in NUCLEO-073RZ

Md_Aslam
Associate II

I Want to use the TIM2 with two channels in "Input capture mode".

CH1--> PA0

CH2-->PA1

Now I have two trigger pulses which I will connect to PA0 and PA1, Signal at PA0 will start the TIM2 and signal at PA1 will stop the TIM2.

So how I can get the counter value of individual channel and calculate the delay between the two trigger pulses?

4 REPLIES 4
Nikita91
Lead II

To start and stop the TIM2 is not the right way.

Let the timer in free running mode. Then when CH1 and CH2 have captured values you can read these values and do CCR2 minus CCR1 to get the delay between the pulses

The TIM only has a single counting element. The ticks will count off at TIMCLK / (PRESCALER+1)

To measure the difference in ticks, subtract one from the other, using the appropriate 16-bit or 32-bit unsigned math depending on TIM's width

Most TIM have four channel latches.

Set the TIM maximal, ie 0xFFFF or 0xFFFFFFFF

Set one channel for rising edge, the other for falling. You can actually use one pin, and map it to the secondary channel via Indirect Mode

For things like servo,I'd use PWM Input Capture, leading edge resets,the one channel gives period count, the other the duty in tick counts.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I did the same, I started TIM2 for both the channels with

HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);

After calling first function, when input will be captured then 

HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) function 

will be called where I can read the counter value and store it in 

some variable. 

But at this time TIM2 is also reset so how I will be able to read the counter 

value for the second channel

my code is as follow:

uint32_t a = 0;

uint32_t b = 0;

uint32_t Difference = 0;

int main()

{

HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);

HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);

while(1)

{

}

}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

{

if ((htim->Instance == TIM2) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1))

{

a = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

}

if ((htim->Instance == TIM2) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2))

{

b = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);

}

if (b > a)

{

Difference = b-a;

}

else if (a > b)

{

Difference = (0xffff - a) + b;

}

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

uart_buf_len = sprintf(buffer, "\nDifference: %lu", Difference);

HAL_UART_Transmit(&huart2, (uint8_t *)buffer, uart_buf_len, 1000);

}

***Please tell me if this approach is better or not?

Nikita91
Lead II

You don't need to reset the TIM2 counter with __HAL_TIM_SET_COUNTER: let the TIM free running and wrap at 0xFFFFFFFF.

To get the captured delay use unsigned so you don't need to test if b>a. You always get the right delay value doing (a-b), if b is captured after a (this is a pro^erty of unsigned arithmetic).

Some remarks about your code:

1) Compute Difference only after the capture of CH2!

2) I don't use HAL, but I think HAL_TIM_IC_CaptureCallback is called from an interrupt handler. It is not recommended to use instructions as long as sprintf and HAL_UART_Transmit in an interrupt handler.