cancel
Showing results for 
Search instead for 
Did you mean: 

Use timer base and input capture at the same time

Yuan1
Associate II

I use timer gated mode for a HC-SR04 ultrasonic sensor which needs microsecond delay. Is it possible to use the same timer as time base to get microseconds?

if (HAL_TIM_Base_Start(&htim3) != HAL_OK)   // time base for usDelay()
		Error_Handler();
if (HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2) != HAL_OK)    // ECHO
		Error_Handler();
...
 
void usDelay (uint16_t uSec)
{
	__HAL_TIM_SET_COUNTER(&htim3, 0);
	while (__HAL_TIM_GET_COUNTER(&htim3) < uSec);
}

The code stuck here.

while (__HAL_TIM_GET_COUNTER(&htim3) < uSec);

5 REPLIES 5
TDK
Guru

Modifying the counter will make your IC readings useless.

However, you can implement the delay without resetting the counter by using the defined overflow behavior. Assuming your counter goes from 0 to 65535:

void usDelay (uint16_t uSec)
{
    uint16_t start = __HAL_TIM_GET_COUNTER(&htim3);
    while ((__HAL_TIM_GET_COUNTER(&htim3) - start) & 0xFFFF <= uSec);
}

You want "<=" to ensure the delay is at least as long as your request. If you use "<" it may be shorter by up to 1us.

A better idea would be to use DWT->CYCCNT counter for highest precision.

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

> gated mode

Delay is going to work unless your timer is running. It's unclear how you're gating it, but it needs to be free running to be used as a clock source for a delay.

If you feel a post has answered your question, please click "Accept as Solution".
Yuan1
Associate II

Thanks, TDK. Your code worked. I also tried DWT, but it only works in debug mode.

DWT works in any mode, although you do need to enable it first.
If you feel a post has answered your question, please click "Accept as Solution".
Yuan1
Associate II

You are right. DWT also works in nondebug mode. Just found out that I forgot to init DWT.

void DWT_Init(void)
{
    if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
        DWT->CYCCNT = 0;
        DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
    }
}