2020-04-16 10:07 AM
Hello,
I need to control signals in the order of nanoseconds magnitude (~ 100 ns). For this purpose, I have programmed a hardware timer in order to have an interrupt with 100 ns delay.
I'm using a STM32F746VE microcontroller at 216 MHz. I'm using the TIM6 as a Base_TIM and I'm programming it with the following configuration:
timConfig.Prescaler = 1;
timConfig.CounterMode = TIM_COUNTERMODE_UP;
timConfig.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timConfig.RepetitionCounter = 0;
timConfig.Period = 5;
timConfig.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
Supposing that APB frequency of the bus is 108 MHz, this is a 111 ns timer (approx.).
Then in order, to measure the real delay of this timer I toggle a GPIO pin in its interruption handler, and measuring the time with an oscilloscope. The interruption handler is the following:
void TIM6_DAC_IRQHandler(void)
{
HAL_TIM_Base_Stop_IT(HAL_TIM6);
if ( i == 0 )
{
GPIOE->BSRR = GPIO_PIN_3;
i = 1;
}
else
{
GPIOE->BSRR = (uint32_t)GPIO_PIN_3 << 16;
i = 0;
}
HAL_TIM_Base_Start_IT(HAL_TIM6);
}
Then, measuring the delay of the interruption is 1.4 us. And if I comment the Stop() and Start() functions I achieve a delay of 235 ns. But not the theoretical 111ns calculated previously with the formula ( T = (1/APB_TIM_CLK) * (PRESCALER_Value + 1) * (PERIOD_Value + 1) ).
Where is the problem here? What happens with HAL_TIME_Base_Start_IT() and HAL_TIME_BASE_Stop_IT()? These funcions add a lot of time.
Thank you in advance.
2020-04-16 11:15 AM
You can't expect to interrupt at 9 MHz !!
Period and Prescaler are N-1
What are the APB clock dividers here?
Set the period to be maximal, and observe elapsed ticks via TIM6->CNT
>>What happens with HAL_TIME_Base_Start_IT() and HAL_TIME_BASE_Stop_IT()? These funcions add a lot of time.
You could use DWT_CYCCNT to measure the elapsed time in 216 MHz ticks.
You could review the listing file and see how much code is actually involved.
2020-04-16 12:17 PM
> signals in the order of nanoseconds magnitude (~ 100 ns)
That's IMO a case for legitimate use of cycle-waste delays. Not that those are trivial on an 'F7.
Still, generating signals in hardware is the first choice in the 32-bitters.
JW
2020-04-17 10:22 AM
Hello,
I have set the period to the maximum value, and then I have used TIM6->CNT in order to perform the nanosecond delay. I have achieved to toggle a pin with 150ns delay. This means a 3.33 MHz frequency. Is possible to improve this value? I suppose that the thing limiting this time, is the time that needs the microcontroller to move the GPIO?
I have used DWT_CYCCNT to measure the Start() and Stop() functions. Each function needs 700ns (this means 1.4us), that is a lot of time...
Thank you a lot!
2020-04-17 02:13 PM
HAL functions are excruciatingly slow, avoid even looking at their general direction when dealing with intervals shorter than 100 microseconds.
You have DWT->CYCCNT, use that to measure 100 ns.
Your system is running on 216 MHz, so 100 ns is 21.6 cycles. It is barely enough to start executing the interrupt handler.