Skip to main content
Yuan1
Associate II
June 10, 2021
Question

Use timer base and input capture at the same time

  • June 10, 2021
  • 5 replies
  • 1327 views

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);

This topic has been closed for replies.

5 replies

TDK
June 10, 2021

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
June 10, 2021

> 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
Yuan1Author
Associate II
June 10, 2021

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

TDK
June 10, 2021
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
Yuan1Author
Associate II
June 10, 2021

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;
 }
}