Electronic – Delays using Timer in stm32

cdelayembeddedstm32timer

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.

Best Answer

Look at your delay_us() function.
How many assembler instructions do you think that will compile to?
Don't forget the stack push/pop and return at the end.
Now, at 16MHz, how long do you think that function will take to execute, assuming the while() at the end just falls straight through.

I threw your function into my GCC-based ARM compiler and, without much optimization enabled, it produced 33 instructions.
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.