2022-09-13 05:23 AM
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?
2022-09-13 02:43 PM
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
2022-09-13 03:45 PM
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.
2022-09-13 10:21 PM
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?
2022-09-14 01:21 AM
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.