2021-06-09 06:52 PM
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);
2021-06-09 07:23 PM
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.
2021-06-09 07:27 PM
> 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.
2021-06-09 08:36 PM
Thanks, TDK. Your code worked. I also tried DWT, but it only works in debug mode.
2021-06-09 08:55 PM
2021-06-09 11:36 PM
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;
}
}