# Delays using Timer in stm32

I am currently trying to achieve delay of 1 uS using timer in stm32 for my application purpose.

SYSCLk is set to 16MHZ LSI and define same for timer clock.
Timer used is a 16 bit timer.
The logic I am using is this.

void delay_us (unsigned int cnt_val)
{
unsigned long x =0;
unsigned int cnt=0,  psc_cnt = 0;
RCC->APB1ENR |= (RCC_APB1ENR_TIM6EN );

x = (unsigned int)((cnt_val * 1000) / 62);
if(x < 65536)
{
cnt = x;
psc_cnt = 0;
}
else
{
cnt = 0xFFFF;
psc_cnt = x / 65536;
}
TIM6->SR = 0x00;
TIM6->ARR = cnt;
TIM6->PSC = psc_cnt;
TIM6->CR1 |= (TIM_CR1_CEN | TIM_CR1_OPM);
while(!(TIM6->SR & TIM_SR_UIF));
RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN);
}


Issue is when i tried to achieve the delay of 1 us i am getting 2.5 us. I checked it by toggling the gpio.

while(1)
{
GPIOA->ODR ^= GPIO_PIN_5;
delay_us(1);
}


can't understand the reason and looking for the solution.

• How about longer times? I guess 1us is comparable with your processor clock and very affected by the overhead of the instruction executed around. – Eugene Sh. Mar 25 '19 at 17:24
• Achieving accurate delays on the order of a microsecond will be difficult using microcontroller software. Why don't you tell us what you plan to do with this delay function? – Elliot Alderson Mar 25 '19 at 17:48
• @EugeneSh. in case of longer times as the error is in microseconds, output is acceptable I tried with 1 sec delay and it works good. – Vaibhav Mar 26 '19 at 7:24
• @ElliotAlderson curiosity as how far can i go. – Vaibhav Mar 26 '19 at 7:25
• If you need this kind of microsecond accuracy you are using the wrong tool. You'd need some beast like a fast-clocked DSP. It can be achieved with a MCU however, by simply executing a bunch of NOP. Not in a loop, but literally just NOP NOP NOP... – Lundin Mar 27 '19 at 16:09

Look at your delay_us() function.
Now, at 16MHz, how long do you think that function will take to execute, assuming the while() at the end just falls straight through.
Considering that your measured 2.5uSec corresponds to about 40 instructions at 16MHz, and adding a few extra instructions for the while(1) loop , the GPIO toggle and the call to the function in your main(), it looks to me as though it's pretty spot-on.